首先我们再来了解一下分片集群的架构,分片集群由三部分构成:
- mongos:查询路由,在客户端程序和分片之间提供接口。本次实验部署2个mongos实例
- config:配置服务器存储集群的元数据,元数据反映分片集群的内所有数据和组件的状态和组织方式,元数据包含每个分片上的块列表以及定义块的范围。从3.4版本开始,已弃用镜像服务器用作配置服务器(SCCC),config Server必须部署为副本集架构(CSRS)。本次实验配置一个3节点的副本集作为配置服务器
- shard:每个shard包含集合的一部分数据,从3.6版本开始,每个shard必须部署为副本集(replica set)架构。本次实验部署3个分片存储数据。
(一)主机信息
(二)配置服务器副本集搭建
配置服务器三个实例的基础规划如下:
member0 192.168.10.80:27017
member1 192.168.10.80:27018
member2 192.168.10.80:27019
其参数规划如下:
接下来,我们一步一步搭建config server的副本集。
STEP1:解压mongodb安装包到/mongo目录
[root@mongosserver mongo]# pwd /@H_502_65@mongo [root@mongosserver mongo]# @H_502_65@ls@H_502_65@ bin LICENSE-Community.txt MPL-2 README THIRD-PARTY-NOTICES THIRD-PARTY-NOTICES.gotools
STEP2:根据上面参数规划,创建数据存放相关路径
# 创建文件路径 @H_502_65@mkdir -p /replset/repset1/@H_502_65@data @H_502_65@log @H_502_65@mkdir -p /replset/repset2/@H_502_65@mkdir -p /replset/repset3/@H_502_65@log [root@mongosserver repset1]# tree /replset/ /replset/@H_502_65@ ├── repset1 │ ├── data │ ├── log │ └── mongodb.conf ├── repset2 │ ├── data │ └── log └── repset3 ├── data └── log
STEP3:为3个实例创建参数文件
实例1的参数文件 /replset/repset1/mongodb.conf :
@H_502_65@systemLog: destination: @H_502_65@file@H_502_65@ logAppend: @H_502_65@true@H_502_65@ path: /replset/repset1/log/@H_502_65@mongodb.log storage: dbPath: /replset/repset1/@H_502_65@data journal: enabled: @H_502_65@ processManagement: fork: @H_502_65@true # fork and run @H_502_65@in@H_502_65@ background pidFilePath: /replset/repset1/@H_502_65@mongod.pid # location of pidfile timeZoneInfo: /usr/share/@H_502_65@zoneinfo # network interfaces net: port: 27017@H_502_65@ bindIp: 0.0.0.0@H_502_65@ # shard sharding: clusterRole: configsvr # repliuca set replication: replSetName: conf
实例2的参数文件 /replset/repset2/mongodb.conf :
@H_502_65@systemLog: destination: file logAppend: @H_502_65@ path: /replset/repset2/log/@H_502_65@mongodb.log storage: dbPath: /replset/repset2/data @H_502_65@ journal: enabled: @H_502_65@ background pidFilePath: /replset/repset2/mongod.pid # location of pidfile timeZoneInfo: /usr/share/zoneinfo @H_502_65@ # network interfaces net: port: 27018@H_502_65@ bindIp: 0.0.0.0@H_502_65@ # shard sharding: clusterRole: configsvr # repliuca set replication: replSetName: conf
实例3的参数文件 /replset/repset3/mongodb.conf :
@H_502_65@ path: /replset/repset3/log/@H_502_65@mongodb.log storage: dbPath: /replset/repset3/@H_502_65@ background pidFilePath: /replset/repset3/@H_502_65@27019@H_502_65@ # shard sharding: clusterRole: configsvr # repliuca set replication: replSetName: conf
STEP4:启动三个mongod实例
mongod -f /replset/repset1/@H_502_65@mongodb.conf mongod -f /replset/repset2/@H_502_65@mongodb.conf mongod -f /replset/repset3/@H_502_65@mongodb.conf # 查看是成功否启动 [root@mongosserver mongo]# netstat -nltp |@H_502_65@grep@H_502_65@ mongod tcp 0 0.0:27019 0.0:* LISTEN 28009/@H_502_65@mongod tcp 27017 27928/@H_502_65@27018 27970/mongod
STEP5:进入任意一个实例,初始化配置服务器的副本集
@H_502_65@rs.initiate( { _id: "conf"@H_502_65@,configsvr: 502_65@ },{ _id : 1,host : "192.168.10.80:27018"502_65@ } ] } )
STEP6:[可选] 调整节点优先级,以便于确定主节点
cfg =@H_502_65@ rs.conf() cfg.members[0].priority = 3@H_502_65@ cfg.members[1].priority = 2@H_502_65@ cfg.members[2].priority = 1@H_502_65@ rs.reconfig(cfg)
对于members[n]的定义:n是members数组中的数组位置,数组以0开始,千万不能将其理解为“members[n]._id”的_id值。
查看节点优先级:
conf:PRIMARY> rs.config()
(三)分片副本集搭建
分片1副本集成员:
member0 192.168.10.81:27017
member1 192.168.10.81:27018
member2 192.168.10.81:27019
分片2副本集成员:
member0 192.168.10.82:27017
member1 192.168.10.82:27018
member2 192.168.10.82:27019
分片3副本集成员:
member0 192.168.10.83:27017
member1 192.168.10.83:27018
member2 192.168.10.83:27019
其参数规划如下:
这里一共有3个分片,每个分片都是3个节点的副本集,副本集的搭建过程与上面config server副本集搭建过程相似,这里不再重复赘述,唯一不同的是副本集的初始化。shard副本集的初始化与配置副本集初始化过程相比,少了 configsvr: @H_502_65@true 的参数配置。
三个shard副本集的初始化:
@H_502_65@# shard001
rs.initiate( { _id: "shard001"502_65@ } ] } )
@H_502_65@# shard002
rs.initiate( { _id: "shard002"502_65@ } ] } ) # shard003 rs.initiate( { _id: "shard003"502_65@ } ] } )
(四)配置并启动mongos
本次试验在192.168.10.100服务器上启动2个mongos进程,分别使用端口27000和28000。
STEP1:配置mongos实例的参数
端口27000参数配置,特别注意,需要先创建涉及到的路径:
@H_502_65@ path: /mongo/log/mongos-27000.log @H_502_65@ processManagement: fork: @H_502_65@ background pidFilePath: /mongo/mongod-27000@H_502_65@.pid # location of pidfile timeZoneInfo: /usr/share/zoneinfo @H_502_65@ # network interfaces net: port: 27000@H_502_65@ sharding: configDB: conf/192.168.10.80:27017,192.168.10.80:27018,192.168.10.80:27019
端口28000参数配置,特别注意,需要先创建涉及到的路径:
@H_502_65@ path: /mongo/log/mongos-28000.log @H_502_65@ background pidFilePath: /mongo/mongod-28000@H_502_65@ # network interfaces net: port: 28000STEP2:启动mongos实例@H_502_65@# 启动mongos实例 [root@mongosserver mongo]# mongos -f /mongo/mongos-27000@H_502_65@.conf [root@mongosserver mongo]# mongos -f /mongo/mongos-28000@H_502_65@.conf # 查看实例信息 [root@mongosserver mongo]# netstat -nltp|@H_502_65@ mongos tcp 27000 2209/@H_502_65@mongos tcp 28000 2241/mongos
(五)添加分片到集群配置服务器
STEP1:使用mongo连接到mongos
mongo --host 192.168.10.100 --port # 或者 mongo --host 28000STEP2:添加分片到集群
@H_502_65@sh.addShard( "shard001/192.168.10.81:27017,192.168.10.81:27018,192.168.10.81:27019"@H_502_65@) @H_502_65@shard002/192.168.10.82:27017,192.168.10.82:27018,192.168.10.82:27019shard003/192.168.10.83:27017,192.168.10.83:27018,192.168.10.83:27019)STEP3:查看分片信息
mongos>@H_502_65@ sh.status() --- Sharding Status ---@H_502_65@ sharding version: { "_id" : 1502_65@) } shards: { "_id" : "shard001","host" : "shard001/192.168.10.81:27017,192.168.10.81:27019","state" : 1@H_502_65@ } { "_id" : "shard002","host" : "shard002/192.168.10.82:27017,192.168.10.82:27019",1)"> } { "_id" : "shard003","host" : "shard003/192.168.10.83:27017,192.168.10.83:27019",1)"> } active mongoses: "4.2.10" : 2@H_502_65@ autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no Failed balancer rounds @H_502_65@in last 5 attempts: 0@H_502_65@ Migration Results @H_502_65@for the last 24@H_502_65@ hours: No recent migrations databases: { "_id" : "config","primary" : "config","partitioned" : @H_502_65@ } mongos>
(六)启用分片
(6.1)对数据库启用分片
分片是以集合为单位进行的,在对一个集合进行分片之前,需要先对其数据库启用分片,对数据库启用分片并不会重新分发数据,只是说明该数据库上的集合可以进行分片操作。sh.enableSharding("lijiamandb");
(6.2)对集合启用分片
如果集合已经存在数据,必须手动创建在分片键上创建索引,然后再对集合进行分片,如果集合为空,MongoDB会在分片的时候自动在分片键上创建索引。
mongodb提供了2种策略来对集合进行分片:
- 哈希(hash)分片,对单列使用hash索引作为分片键
sh.shardCollection("<database>.<collection>",{shard key field : "hashed"})
- 范围(range)分片,可以使用多个字段作为分片键,并将数据划分为由分片键确定的连续范围
sh.shardCollection("<database>.<collection>",{<shard key field>:1,...} )
例子:对集合user进行hash分片
@H_502_65@//@H_502_65@ 连接到mongos,进入lijiamandb数据库,对新集合users插入10万条数据 @H_502_65@use lijiamandb @H_502_65@for (i=1;i<100000;i++@H_502_65@){ db.user.insert({ "id"@H_502_65@ : i,"name" : "name"+@H_502_65@i,"age" : Math.floor(Math.random()*120@H_502_65@),"created" : @H_502_65@new@H_502_65@ Date() }); } @H_502_65@ 使用mongostat可以看到,所有数据都写入到了主节点(shard2),每个数据库的主节点可能不同,可以使用sh.status()查看。 [root@mongosserver ~]# mongostat --port 27000 5 --@H_502_65@discover host insert query update @H_502_65@delete@H_502_65@ getmore command dirty used flushes mapped vsize res faults qrw arw net_in net_out conn set repl time localhost:27000 352 *0 *0 *0 0 704|0 0 0B 356M 32.0M 0 0|0 0|0 224k 140k 10 RTR Jan 15 10:52:32.046@H_502_65@ host insert query update @H_502_65@ getmore command dirty used flushes mapped vsize res faults qrw arw net_in net_out conn set repl time 192.168.10.81:27017 *0 *0 *0 *0 0 2|0 0.3% 0.8% 0 1.90G 133M n/a 0|0 1|0 417b 9.67k 23 shard001 SEC Jan 15 10:52:32.061 192.168.10.81:27018 *0 *0 *0 *0 0 3|0 0.3% 0.8% 1 1.93G 132M n/a 0|0 1|0 1.39k 11.0k 28 shard001 PRI Jan 15 10:52:32.067 192.168.10.81:27019 *0 *0 *0 *0 0 2|0 0.3% 0.8% 0 1.95G 148M n/a 0|0 1|0 942b 10.2k 26 shard001 SEC Jan 15 10:52:32.070 192.168.10.82:27017 352 *0 *0 *0 407 1192|0 2.5% 11.7% 1 1.99G 180M n/a 0|0 1|0 1.52m 1.15m 29 shard002 PRI Jan 15 10:52:32.075 192.168.10.82:27018 *352 *0 *0 *0 409 441|0 4.5% 8.9% 0 1.96G 163M n/a 0|0 1|0 566k 650k 25 shard002 SEC Jan 15 10:52:32.085 192.168.10.82:27019 *352 *0 *0 *0 0 2|0 4.4% 9.7% 0 1.92G 168M n/a 0|0 1|0 406b 9.51k 24 shard002 SEC Jan 15 10:52:32.093 192.168.10.83:27017 *0 *0 *0 *0 0 1|0 0.2% 0.6% 1 1.89G 130M n/a 0|0 1|0 342b 9.17k 22 shard003 SEC Jan 15 10:52:32.099 192.168.10.83:27018 *0 *0 *0 *0 0 2|0 0.2% 0.6% 0 1.95G 139M n/a 0|0 1|0 877b 9.92k 28 shard003 PRI Jan 15 10:52:32.107 192.168.10.83:27019 *0 *0 *0 *0 0 1|0 0.2% 0.6% 0 1.90G 133M n/a 0|0 1|0 342b 9.17k 21 shard003 SEC Jan 15 10:52:32.113 localhost:27000 365 *0 *0 *0 0 731|0 0 0B 356M 32.0M 0 0|0 0|0 233k 145k 10 RTR Jan 15 10:52:37.047 @H_502_65@ 使用分片键id创建hash分片,因为id上没有hash索引,会报错 sh.shardCollection("lijiamandb.user",{"id":"hashed"@H_502_65@}) @H_502_65@/*@H_502_65@ 1 @H_502_65@*/@H_502_65@ { "ok" : 0.0502_65@ : { "clusterTime" : Timestamp(1610679762,"signature"@H_502_65@ : { "hash" : { "$binary" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=","$type" : "00"502_65@) } } } @H_502_65@ 需要手动创建hash索引 @H_502_65@db.user.ensureIndex() @H_502_65@ 查看索引@H_502_65@ /*@H_502_65@ [ { "v" : 2502_65@ : { "_id" : 1@H_502_65@ },"name" : "_id_"502_65@ },{ "v" : 2@H_502_65@ : { "id" : "hashed"502_65@ } ] @H_502_65@# 最后再重新分片即可 sh.shardCollection("lijiamandb".user,{"id":"hashed"})
到这里,我们分片集群环境已经搭建完成,接下来我们将会学习分片键的选择机制。
【完】
相关文档合集: 1. MongoDB Sharding(一) -- 分片的概念 |