一、前言
考虑这样一个场景,有个数据量有10多亿数据的设备库,里面存放了注册的设备的信息,并且设备数据还可能会递增,然后业务集群需要对指定条件的设备群发信息,那么如何才能高效的来处理这个问题那?
二、思考
2.1 离线分析
为了不影响在线业务,以往需要把一份数据进行多次复制来分别进行业务交易和数据分析的问题,也就是业务交易的数据是在原来的库,而数据分析是通过手段把原来库数据定时同步到另外的存储设备离线分析。上面所说消息群发设备就可以使用这种方式,首先全量把数据同步到另外的存储设备,然后在定时把原来库里面的新数据增量到存储设备。
2.2 离线库
2.2.1 阿里云产品mondb介绍
对于存储设备可以选择阿里云产品MongoDB,原因是MongoDB 分片集群(Sharded Cluster)通过将数据分散存储到多个分片(Shard)上来实现高可扩展性。实现分片集群时,MongoDB 引入 Config Server 来存储集群的元数据,引入 mongos 作为应用访问的入口,mongos 从 Config Server 读取路由信息,并将请求路由到后端对应的 Shard 上。下面看下原理图
用户访问 mongos 跟访问单个 mongod 类似;
所有 mongos 是对等关系,用户访问分片集群可通过任意一个或多个mongos;
mongos 本身是无状态的,可任意扩展,集群的服务能力为“Shard服务能力之和”与“mongos服务能力之和”的最小值;
访问分片集群时,最好将应用负载均匀的分散到多个 mongos 上。
Sharding Cluster使得集合数据被分散到多个Shard存储,也就是每个shard存放整体数据的一部分
2.2.2 如何正确地连接分片集群?
所有官方的 MongoDB driver 都支持以 Connection String 的方式来连接 MongoDB 分片集群。
下面就是 Connection String 包含的主要内容:
mongodb://[username:password@]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/[database][?options]]
mongodb:// 前缀,代表这是一个Connection String;
username:password@ 如果启用了鉴权,需要指定用户密码;
hostX:portX多个 mongos 的地址列表;
/database鉴权时,用户帐号所属的数据库;
?options 指定额外的连接选项。
2.2.3 java 代码访问
通过 java 来连接的示例代码如下所示:
MongoClientURI connectionString = new MongoClientURI("mongodb://:****@s-m5e80a9241323604.mongodb.rds.aliyuncs.com:3717,s-m5e053215007f404.mongodb.rds.aliyuncs.com:3717/admin"); // ****替换为root密码MongoClient client = new MongoClient(connectionString);MongoDatabase database = client.getDatabase("mydb");MongoCollection collection = database.getCollection("mycoll");
通过上述方式连接分片集群时,客户端会自动将请求分散到多个 mongos 上,以实现负载均衡;同时,当 URI 里 mongos 数量在2个及以上时,当有 mongos 故障时,客户端能自动进行 failover,将请求都分散到状态正常的 mongos 上。
好吧,言归正传,上面知道大数据最后会被分散到不同的shard上,而我们的应用系统是集群,如果能让集群每台机器分摊不同shard上的数据进行处理,那么性能肯定杠杠的,可以吗?答案是必须的。
mongb上有个config.shards,config.shards集合存储各个Shard的信息,可通过addShard、removeShard命令来动态的从Sharded cluster里增加或移除shard。
mongos> db.shards.find(){ "_id" : "mongo-9003", "host" : "mongo-9003/10.1.72.135:9003,10.1.71.136:9003,10.1.72.137:9003" }{ "_id" : "mongo-9004", "host" : "mongo-9004/10.1.72.135:9004,10.1.71.136:9004,10.1.72.137:9004" }
通过config.shards可以获取所以分片shard的地址然后替换上面的url中host,就可以让集群系统里不同机器直接访问shard上的数据。