天堂极乐鸟

导航

MongoDB在Windows下单机分片集群配置

基本配置

MongoDB版本

4.4

端口设置

分片0副本集rs0:27000,27001,27002
分片1副本集rs1:27010,27011,27012
分片2副本集rs2:27020,27021,27022
配置服务器副本集:27100,27101,27102
路由服务器mongos:27200

MongoDB文件夹设置

新建文件夹

data0-0,data0-1,data0-2,
data1-0,data1-1,data1-2,
data2-0,data2-1,data2-2,
conf0,conf1,conf2,

新建文件

rs0-0.conf,rs0-1.conf,rs0-2.conf,
rs1-0.conf,rs1-1.conf,rs1-2.conf,
rs2-0.conf,rs2-1.conf,rs2-2.conf,

(此处配置服务器副本集没有使用配置文件方式启动,而是直接使用命令)

各个配置文件中的内容

例如rs0-0.conf:分别是数据库文件路径,日志输出路径,日志是否在文件后面追加,是否是分片结点,副本集名称(同一个分片的副本集名称一样),端口
注意:部署分片集群的分片副本集必须带shardsvr参数,下面的配置服务器副本集必须带configsvr参数,不然要删了data文件夹重新弄

dbpath=D:\MongoDB\data0-0
logpath=D:\MongoDB\log\data0-0.log
logappend=true
shardsvr=true
replSet=rs0
port=27000

启动

启动分片副本集

//打开一个cmd,开启一个副本集成员

mongod -f d:\MongoDB\rs0-0.conf

//打开一个cmd,开启一个副本集成员

mongod -f d:\MongoDB\rs0-1.conf

//打开一个cmd,开启一个副本集成员

mongod -f d:\MongoDB\rs0-2.conf

//打开一个cmd用来配置副本集

mongo --port 27000

//设置配置内容,前一个id是副本集的id,后一个id是副本集成员的id,第一个设置为0,将来增加时会自动自增

rsconf = {_id: "rs0",members: [{_id: 0,host: "127.0.0.1:27000"}]}

//使用配置初始化

rs.initiate( rsconf )

//显示{"ok":1}
//查看信息

rs.conf() 

//增加两个新的副本集成员

rs.add("127.0.0.1:27001")
rs.add("127.0.0.1:27002")

//再次查看信息和状态

rs.conf()
rs.status()

用同样的方式再启动rs1和rs2分片副本集

启动配置服务器副本集

//打开一个cmd作为config服务器
此处配置服务器不使用配置文件而是使用命令参数启动,两种方法都可以

mongod --configsvr --port 27100 --dbpath d:\MongoDB\conf0 --replSet conf

//打开一个cmd作为config服务器

mongod --configsvr --port 27101 --dbpath d:\MongoDB\conf1 --replSet conf

//打开一个cmd作为config服务器

mongod --configsvr --port 27102 --dbpath d:\MongoDB\conf2 --replSet conf

//打开一个cmd用来配置副本集

mongo --port 27100

//设置配置内容,前一个id是副本集的id,后一个id是副本集成员的id,第一个设置为0,将来增加时会自动自增

rsconf = {_id: "conf",members: [{_id: 0,host: "127.0.0.1:27100"}]}

//使用配置初始化

rs.initiate( rsconf )

//显示{"ok":1}
//查看信息

rs.conf() 

//增加两个新的副本集成员

rs.add("127.0.0.1:27101")
rs.add("127.0.0.1:27102")

//再次查看信息和状态

rs.conf() <div><br/></div>rs.status()

启动路由服务器

//打开一个mongos,指定config服务器,其中conf是config服务器的副本集名字
(此处只使用一个mongos)

mongos --configdb conf/127.0.0.1:27100,127.0.0.1:27101,127.0.0.1:27102 --port 27200

配置分片集群

添加分片

//在mongo客户端打开

mongo --port 27200

//添加分片

sh.addShard("rs0/127.0.0.1:27000,127.0.0.1:27001,127.0.0.1:27002")
sh.addShard("rs1/127.0.0.1:27010,127.0.0.1:27011,127.0.0.1:27012")
sh.addShard("rs2/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022")

设置哈希分片

//设置要分片的数据库

sh.enableSharding("test1")

//设置_id字段为哈希分片键

sh.shardCollection("test1.test11", { "_id": "hashed" } )

//为集合增加数据

use test1<div><br/></div>for(i=0;i<100;i++){ db.test11.insert({"name" : "a", "age" : 16}); }

//查看状态

rs.status()

可以看到:三个分片里分别有两个chunk,共6个chunk,每个chunk里的id分布如下所示,分界的数字是一个19位的10进制数字,而_id是一个24位的16进制数字,所以这个19位的数字是hash后的值。

打开studio T3,分别连接rs0(27000)、rs1(27010)、rs2(27020)和mongos(27200)
可以看到mongos中共有所有的100条数据,而其他三个分片中分别有156、175、169条数据,总数为500。而且同一个分片副本集下的服务器的数据相同。

设置范围分片

//设置数据库

sh.enableSharding("test2")

//设置id字段为范围分片键

sh.shardCollection("test2.test21",{id: 1}  )

//增加数据,id为-30000至30000

use test2
for(i=-30000;i<30000;i++){ db.test21.insert({"id":i,"name":"aa","age":22}); }

//查看状态

rs.status()

可以看到共有5个chunk:
rs0:min至-29999,9672至max
rs1:-29999至-12523
rs2:-12523至-1268,-1268至9672
根据插入数据id范围为-30000至30000,可知rs0中应该有20329条数据,rs1中应该有17476条数据,rs2中应该有22195条数据。

打开studio T3,分别连接rs0(27000)、rs1(27010)、rs2(27020)和mongos(27200)
可以看到mongos中共有所有的60000条数据,而其他三个分片中分别有20329、17476、22195条数据,总数为60000。而且同一个分片副本集下的服务器的数据相同。
且查看到的数据确实在范围内,因此说明配置成功。

其他配置

修改chunkSize

(在mongos中)
//chunkSize用来设置每个chunk的大小,单位为MB,范围为1-1024之间
//只需设定分片键,chunk的范围是自动生成的,rs.status()显示的每一个范围就是一个chunk的范围,chunk会在分片中移动,确保每个分片的数据量差不多

use config
db.settings.insertOne( { _id:"chunksize", value: <sizeInMB> } )

注意:使用rs.status()可以看到显示数据库的“primary”:“rs2”,说明该数据库的主分片为rs2,
Primary(主)是MongoDB复制集中的最重要的角色,是能够接受客户端/Driver写请求的节点,(读请求也是默认路由到Primary节点)。
因此在批量写入数据时,会看到rs2中的数据量和mongos中数据量相同,但是过一会儿之后就只保留自己分片的哪一部分数据了。

启动集群

只需使用mongod逐一启动9个分片服务器,3个配置服务器,1个路由服务器即可,然后使用cmd连接mongos,中间报错不用管,只要最后mongos连上即可。

分片增删

删除分片

删除分片是删除所有数据库中的该分片,而不只是一个数据库的分片
首先,如果要删除的分片是某些分片数据库的primary,则需要先将所有分片了的数据库的primary交给其他分片,执行以下命令

db.adminCommand( { movePrimary: "test2", to: "rs0" })

删除分片rs2

db.adminCommand({removeShard:"rs2"})

会显示state为started,表示开始执行转移数据的操作
再次执行这条语句,会显示state为ongoing,表示操作正在进行,直到最后显示completed表示结束。
注意:无论自己的数据库中有多少数据,这个过程都非常久,将近一个小时,因为有个系统自带的数据库里有几百个chunk要移动

删除完成后,使用rs.status()命令可以看到原本属于rs2的chunk被搬到了其他分片

studio T3中看到的数据条数(rs2中都数据条数为0):
test1:

test2:

增加分片

在删除rs2后还要删除rs2中的test1和test2数据库,否则会和其他分片中的同名数据库产生冲突。
//增加分片

sh.addShard("rs2/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022")

然后使用rs.status()命令可以看到又为rs2设置了chunk

studio T3中看到的数据条数:
test1:

test2:(新增加的rs2只分到一个chunk且正好这个chunk中只有一条数据)

分片集群与副本集在读写方面的主要区别

读取复制集操作

默认情况下,客户端读取复制集的主副本;但是,客户端可以指定一个读首选项 ,以便对其他成员进行直接读操作。例如,客户端可以配置读取偏好,从二级或从最近的成员读取到。

在复制集上进行写操作

在复制集,中,所有的写操作都指向集合的主节点。主服务器应用写操作并将操作记录在主服务器的操作日志或oplog上。oplog是对数据集的可重复操作序列。集合中的次要成员不断复制oplog,并在一个异步进程中将这些操作应用到自己身上。

读取分片集群操作

对于分片群集,应用程序向mongos与该群集关联的实例之一发出操作 。当分片群集上的读取操作定向到特定分片时,效率最高。分片集合的查询应包含集合的分片键。当查询包含分片键时,mongos可以使用配置数据库中的群集元数据将查询路由到分片。
如果查询不包含分片键,则mongos必须将查询定向到集群中的所有分片。这些分散的收集查询可能效率很低。在较大的群集上,分散收集查询对于常规操作是不可行的。

在分片群集上写操作

对于分片群集中的分片集合,该 mongos指令将写操作从应用程序定向到负责数据集特定部分的分片。在mongos使用来自集群的元数据 的配置数据库以路由写操作到适当的分片。
MongoDB根据分片键的值将分片集合中的数据划分为范围。然后,MongoDB将这些块分配为分片。分片键决定块到分片的分布。这可能会影响集群中的写操作的性能。
影响单个文档的 更新操作必须包含分片键 或_id 字段。如果具有分片键,则影响多个文档的更新在某些情况下会更有效,但可以广播到所有分片。

参考

https://www.cnblogs.com/jasonlwings/p/7462683.html
https://www.cnblogs.com/clsn/p/8214345.html

posted on 2021-09-11 15:11  天堂极乐鸟  阅读(231)  评论(0编辑  收藏  举报