MongoDB学习(七):集群之分片集

目录

1 概念

2 建立分片集

1)启动mongod、mongos进程

2)配置集群

3)分配集合

3 客户端连接


MongoDB学习(六):集群之复制集 提到,复制集(副本集)在数据量过大,以至于无法全部装载到内存中时,分布式架构也很难提升系统性能。MongoDB的方案是分片。

1 概念

所谓分片,就是将大数据集分割为较小的数据集的过程。之前使用MongoDB的过程中,无论是单节点 or 复制集,每个服务器都保存了全量数据。这就带来两个问题:首先,随着数据增长,单台服务器的处理能力逐渐到达极限(内存无法装下所有数据);其次,由于数据过大,新节点进行初始化的全量同步时,很可能出现卡死的问题(I/O导致CPU不足)。

分片集群的相关组件如下:

  • 分片(Shards):每个分片存储了完整数据的一部分,实际是一个单节点服务器or复制集。只有路由和管理员可以直接访问分片。
  • 路由(Routers):存储了集群元数据,用来查找操作的数据在哪个分片上。
  • 配置服务器(Config Servers):持久化集群元数据,例如每个分片存储了哪部分数据。

另一个问题是,MongoDB分片的粒度。在MongoDB中,有数据库、集合、文档等结构,实际上,在集合和文档之间,还存在一中名为“块”的概念,指的是根据一个或多个字段(称为分片键)的值聚集的一系列文档。分片是在数据库和块这两级上进行的。

实际上,数据库级的分片是手动的,即我们必须保证每个分片上的每个数据库所包含的数据都大致均衡。如果有某个数据库存放了过多数据,就需要对其进行分库。

在块上的分片则是自动进行的,根据指定的分片键的值,将整个值域分割为多个区间,每个区间映射到一个分片上。例如一共分两个片,分片键的值以A~Z开头,那么可能A~E分到分片1,F~J分到分片2……

2 建立分片集

建立分片集的步骤如下,这里以两个分片为例:

1)启动mongod、mongos进程

首先,需要为每个分片创建复制集,步骤参见MongoDB学习(六):集群之复制集

以分片A为例:

root@Ubuntu:~# mkdir -p  ~/rs/a-1
root@Ubuntu:~# mkdir -p  ~/rs/a-2
root@Ubuntu:~# mkdir -p  ~/rs/a-3
root@Ubuntu:~# mongod --sharedsvr --replSet shard-a --dbpath ~/rs/a-1 --port 30000 --logpath ~/rs/a-1.log --fork
root@Ubuntu:~# mongod --sharedsvr --replSet shard-a --dbpath ~/rs/a-2 --port 30001 --logpath ~/rs/a-1.log --fork
root@Ubuntu:~# mongod --sharedsvr --replSet shard-a --dbpath ~/rs/a-3 --port 30002 --logpath ~/rs/a-1.log --fork

然后连接端口为30000的服务器,使用rs.initiate()进行复制集初始化,添加30001服务器为从节点,30002服务器为仲裁节点。 

分片B如法创建。然后创建配置服务器:

root@Ubuntu:~# mkdir -p  ~/rs/config-1
root@Ubuntu:~# mkdir -p  ~/rs/config-2
root@Ubuntu:~# mkdir -p  ~/rs/config-3
root@Ubuntu:~# mongod --configsvr --dbpath ~/rs/config-1 --port 30200 --logpath ~/rs/config-1.log --fork --nojournal
root@Ubuntu:~# mongod --configsvr --dbpath ~/rs/config-1 --port 30201 --logpath ~/rs/config-2.log --fork --nojournal
root@Ubuntu:~# mongod --configsvr --dbpath ~/rs/config-1 --port 30202 --logpath ~/rs/config-3.log --fork --nojournal

注意配置服务器不要带--replSet选项。

然后启动mongos:

root@Ubuntu:~# mongos --configdb localhost:30200,localhost:30201,localhots:30202 --logpath ~/mongos.log --fork --port 30300

然后就可以连接mongos服务器进行配置了。

2)配置集群

可以使用sh.help()查询可用的命令。

主要用到的方法是sh.addShard()

> sh.addShard("shard-a/localhost:30000,localhost:30001")

30002是仲裁节点,不存储数据,所以不用添加。shard-b添加方式类似。 

然后就可以使用db.getSiblingDB("config").shards.find()查询当前所有的分片。

以下方法可以查看块的数量:

> use config
> db.chunks.count()

假如传入{"shard":"shard-a"}作为参数,则是查询分片A上的块数。

块信息实际存放在chunks集合中,可以使用find()方法查看其信息,如分片键范围等。 

3)分配集合

假设要在test数据库上启用分片,则:

> sh.enableSharding("test")

可以使用db.getSiblingDB("config").databases.find()查询配置结果。

现在可以对集合进行分片了,假设集合名为user,以username和_id作为分片键:

> sh.shardCollection("test.user",{username:1,_id:1})

可以使用db.getSiblingDB("config").collections.find()查询配置结果。

假如要删除一个分片,可以使用runCommand函数,以下命令删除了分片A:

> use admin
> db.runCommand({removeshard:"shard-a/localhost:30000,localhost:30001"})

块分片不是固定的,可能会出现块转移的情况(原来的块膨胀,导致发生了块分裂,分裂后的块就需要进行迁移),可以用以下命令查询:

> use config
> db.changelog.find({what:"moveChunk.commit"})

可以使用sh.splitAt("test.user",{username:"somename",_id:ObjectId("someid")})在指定点切分块

可以使用sh.moveChunk("test.user",{username:"somename"},"shardB")将某个块转移到分片B

3 客户端连接

假如mongos启动在27017端口上,可以直接MongoClients.create():

MongoClient mongoClient = MongoClients.create();

否则传入url即可,字符串 或 ConnectionString均可:

MongoClient mongoClient = MongoClients.create("mongodb://localhost:30300");

也可以以ClusterSettings+MongoClientSettings的形式传入url:

ClusterSettings clusterSettings = ClusterSettings.builder()
                                    .hosts(asList(new ServerAddress("localhost:30300")))
                                    .build();
MongoClientSettings settings = MongoClientSettings.builder()
                                    .clusterSettings(clusterSettings)
                                    .build();
MongoClient mongoClient = MongoClients.create(settings);

如果有多个mongos实例,只要用逗号隔开每个url即可:

MongoClient mongoClient = MongoClients.create("mongodb://host1:27017,host2:27017");

ClusterSettings+MongoClientSettings的形式更简单,因为hosts方法里传入的是个List,只要往List中多放几个元素就行。

剩下的操作和单节点没什么区别了。

猜你喜欢

转载自blog.csdn.net/u010670411/article/details/86828762