mongodb_基础到进阶 – MongoDB 高级–MongoDB 集群部署与安全性(四)
一、mongodb 第一个路由节点创建
1、分片集群架构目标
两个分片节点副本集(3+3)+一个配置节点副本集(3)+两个路由节点(2),共11个服务节点。
2、mongodb 第一个路由节点创建:第一步:准备存放数据和日志的目录:
#-----------mongos01mkdir -p /usr/local/mongodb/sharded_cluster/mymongos_27017/log
3、mongodb 第一个路由节点创建::第二步:新建或修改配置文件(mymongos_27017节点):
vim /usr/local/mongodb/sharded_cluster/mymongos_27017/mongos.conf# mymongos_27017 内容如下(注意 yaml 文件格式):systemLog:# MongoDB发送所有日志输出的目标指定为文件destination: file# mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/usr/local/mongodb/sharded_cluster/mymongos_27017/log/mongod.log"# 当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾logAppend: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27017/log/mongod.pid"
net:#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll: true#服务实例绑定的IPbindIp: localhost,172.18.30.110# bindip# 绑定的端口port: 27017
sharding:#指定配置节点副本集configDB: myconfigrs/172.18.30.110:27019,172.18.30.110:27119,172.18.30.110:27219
4、mongodb 第一个路由节点创建::第三步:启动 mongos 服务::
# 切换目录
cd /usr/local/mongodb/# 启动 MongoDB 服务
[root@WIN-20240529BJA:/usr/local/mongodb#] /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27017/mongos.conf# 查看进程,mongodb 是否启动成功
[root@WIN-20240529BJA:/usr/local/mongodb#] ps -ef | grep mongodroot 4542 1 0 11:37 ? 00:03:27 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27018/mongod.conf
root 4596 1 0 11:41 ? 00:03:32 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27118/mongod.conf
root 4648 1 0 11:41 ? 00:03:21 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27218/mongod.conf
root 4712 1 0 11:48 ? 00:03:32 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27318/mongod.conf
root 4764 1 0 11:49 ? 00:03:33 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27418/mongod.conf
root 4816 1 0 11:49 ? 00:03:22 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27518/mongod.conf
root 4943 1 0 15:32 ? 00:01:30 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27019/mongod.conf
root 4997 1 0 15:32 ? 00:01:38 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27119/mongod.conf
root 5051 1 0 15:33 ? 00:01:39 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27219/mongod.conf
root 5115 2216 0 15:36 pts/4 00:00:00 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27019
root 5178 2067 0 15:46 pts/0 00:00:00 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27018
root 5460 1337 0 16:21 pts/2 00:00:00 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27318
root 6493 1 0 18:13 ? 00:00:02 /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27017/mongos.conf
root 6684 2289 0 18:28 pts/5 00:00:00 grep --color=auto mongod
root@WIN-20240529BJA:/usr/local/mongodb#
5、mongodb 第一个路由节点创建::第四步:客户端登录 mongos
# 切换目录
cd /usr/local/mongodb/# 启动 MongoDB 服务
[root@WIN-20240529BJA:/usr/local/mongodb#] /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27017mongos> show dbs
admin 0.000GB
config 0.000GBmongos> use mongotest
switched to db mongotestmongos> db.mongotest.insert({aa:"aa"})
WriteCommandError({"ok" : 0,"errmsg" : "Database mongotest could not be created :: caused by :: No shards found","code" : 70,"codeName" : "ShardNotFound","$clusterTime" : {"clusterTime" : Timestamp(1722508482, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722508482, 1)
})
mongos>
此时,写不进去数据,如果写数据会报错:
原因是:通过路由节点操作,现在只是连接了配置节点,还没有连接分片数据节点,因此无法写入业务数据。
6、properties 配置文件参考::
logpath=/usr/local/mongodb/sharded_cluster/mymongos_27017/log/mongos.log
logappend=true
bind_ip_all=true
port=27017
fork=true
configdb=myconfigrs/172.18.30.110:27019,172.18.30.110:27119,172.18.30.110:27219
二、mongodb 路由节点进行分片操作
1、使用命令添加分片:添加分片 语法:
sh.addShard("IP:Port")
2、将第一套分片副本集添加进来
# 打开另一终端,查看节点信息# 切换目录
cd /usr/local/mongodb/# 连接 第一套 分片副本集 的 MongoDB 服务
[root@WIN-20240529BJA:/usr/local/mongodb#] /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27018
myshardrs01:PRIMARY>
myshardrs01:PRIMARY> rs.status()
{"set" : "myshardrs01","date" : ISODate("2024-08-01T08:15:09.856Z"),"myState" : 1,"term" : NumberLong(1),"syncSourceHost" : "","syncSourceId" : -1,"heartbeatIntervalMillis" : NumberLong(2000),"majorityVoteCount" : 2,"writeMajorityCount" : 2,"votingMembersCount" : 3,"writableVotingMembersCount" : 2,"optimes" : {"lastCommittedOpTime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"lastCommittedWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"readConcernMajorityOpTime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"appliedOpTime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"durableOpTime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"lastAppliedWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"lastDurableWallTime" : ISODate("2024-08-01T08:15:01.594Z")},"lastStableRecoveryTimestamp" : Timestamp(1722500071, 1),"electionCandidateMetrics" : {"lastElectionReason" : "electionTimeout","lastElectionDate" : ISODate("2024-08-01T07:47:30.697Z"),"electionTerm" : NumberLong(1),"lastCommittedOpTimeAtElection" : {"ts" : Timestamp(1722498449, 1),"t" : NumberLong(-1)},"lastSeenOpTimeAtElection" : {"ts" : Timestamp(1722498449, 1),"t" : NumberLong(-1)},"numVotesNeeded" : 1,"priorityAtElection" : 1,"electionTimeoutMillis" : NumberLong(10000),"newTermStartDate" : ISODate("2024-08-01T07:47:31.266Z"),"wMajorityWriteAvailabilityDate" : ISODate("2024-08-01T07:47:31.570Z")},"members" : [{"_id" : 0,"name" : "172.18.30.110:27018","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 16654,"optime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2024-08-01T08:15:01Z"),"lastAppliedWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"lastDurableWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"syncSourceHost" : "","syncSourceId" : -1,"infoMessage" : "","electionTime" : Timestamp(1722498450, 1),"electionDate" : ISODate("2024-08-01T07:47:30Z"),"configVersion" : 3,"configTerm" : 1,"self" : true,"lastHeartbeatMessage" : ""},{"_id" : 1,"name" : "172.18.30.110:27118","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 370,"optime" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"optimeDurable" : {"ts" : Timestamp(1722500101, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2024-08-01T08:15:01Z"),"optimeDurableDate" : ISODate("2024-08-01T08:15:01Z"),"lastAppliedWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"lastDurableWallTime" : ISODate("2024-08-01T08:15:01.594Z"),"lastHeartbeat" : ISODate("2024-08-01T08:15:08.836Z"),"lastHeartbeatRecv" : ISODate("2024-08-01T08:15:08.863Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncSourceHost" : "172.18.30.110:27018","syncSourceId" : 0,"infoMessage" : "","configVersion" : 3,"configTerm" : 1},{"_id" : 2,"name" : "172.18.30.110:27218","health" : 1,"state" : 7,"stateStr" : "ARBITER","uptime" : 337,"lastHeartbeat" : ISODate("2024-08-01T08:15:08.843Z"),"lastHeartbeatRecv" : ISODate("2024-08-01T08:15:09.219Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncSourceHost" : "","syncSourceId" : -1,"infoMessage" : "","configVersion" : 3,"configTerm" : 1}],"ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722500101, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722500101, 1)
}
myshardrs01:PRIMARY>
3、将第一套、第二套分片副本集 添加进来(myshardrs01,myshardrs02 )
# 切换目录
cd /usr/local/mongodb/# 连接 27017 端口的 MongoDB 服务
root@WIN-20240529BJA:/usr/local/mongodb# /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27017# 在 27017 节点 将第一套分片副本集添加进来
mongos> sh.addShard("myshardrs01/172.18.30.110:27018,172.18.30.110:27118,172.18.30.110:27218"){"shardAdded" : "myshardrs01","ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722520734, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722520734, 1)
}
mongos> # 在 27017 节点 将第二套分片副本集添加进来
mongos> sh.addShard("myshardrs02/172.18.30.110:27318,172.18.30.110:27418,172.18.30.110:27518"){"shardAdded" : "myshardrs02","ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722520911, 5),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722520911, 4)
}
mongos>
4、在 27017 节点 查看 分片副本集状态情况
mongos> sh.status()
--- Sharding Status --- sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("66ab4772678657abc1742829")}shards:{ "_id" : "myshardrs01", "host" : "myshardrs01/172.18.30.110:27018,172.18.30.110:27118", "state" : 1, "topologyTime" : Timestamp(1722520733, 1) }{ "_id" : "myshardrs02", "host" : "myshardrs02/172.18.30.110:27318,172.18.30.110:27418", "state" : 1, "topologyTime" : Timestamp(1722520911, 2) }active mongoses:"5.0.28" : 1autosplit:Currently enabled: yesbalancer:Currently enabled: yesCurrently running: yesCollections with active migrations: config.system.sessions started at Thu Aug 01 2024 22:04:09 GMT+0800 (CST)Failed balancer rounds in last 5 attempts: 0Migration results for the last 24 hours: 29 : Successdatabases:{ "_id" : "config", "primary" : "config", "partitioned" : true }config.system.sessionsshard key: { "_id" : 1 }unique: falsebalancing: truechunks:myshardrs01 995myshardrs02 29too many chunks to print, use verbose if you want to force print
mongos>
5、提示:如果添加分片失败,需要先手动移除分片,检查添加分片的信息的正确性后,再次添加分片。
1)移除分片参考:
use admin
db.runCommand( { removeShard: "myshardrs02" } )
2)注意:如果只剩下最后一个 shard,是无法删除的,移除时会自动转移分片数据,需要一个时间过程。
完成后,再次执行删除分片命令才能真正删除。
6、开启分片功能:sh.enableSharding(“库名”)、sh.shardCollection(“库名.集合名”,{“key”:1})
在 mongos 上的 articledb 数据库配置 sharding:
mongos> sh.enableSharding("articledb"){"ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722526608, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722526607, 2)
}
mongos>
7、集合分片
1)对集合分片,你必须使用 sh.shardCollection() 方法指定集合和分片键。
2)语法:
sh.shardCollection(namespace, key, unique)
3)参数:
Parameter | Type | Description | |
---|---|---|---|
namespace | string | 要(分片)共享的目标集合的命名空间,格式: . | |
key | document | 用作分片键的索引规范文档。shard键决定MongoDB如何在shard之间分发文档。除非集合为空,否则索引必须在shard collection命令之前存在。如果集合为空,则MongoDB在对集合进行分片之前创建索引,前提是支持分片键的索引不存在。简单的说:由包含字段和该字段的索引遍历方向的文档组成。 | |
unique | boolean | 当值为true情况下,片键字段上会限制为确保是唯一索引。哈希策略片键不支持唯一索引。默认是false。 | |
三、mongodb 分片策略 哈希&范围演示
1、对集合进行分片时,你需要选择一个 片键(Shard Key) , shard key 是每条记录都必须包含的,且建立了
索引的单个字段或复合字段,MongoDB按照片键将数据划分到不同的 数据块 中,并将 数据块 均衡地分布
到所有分片中.为了按照片键划分数据块,MongoDB使用 基于哈希的分片方式(随机平均分配)或者基
于范围的分片方式(数值大小分配) 。
- 用什么字段当片键都可以,如:nickname 作为片键,但一定是必填字段。
2、分片规则一:哈希策略
-
对于 基于哈希的分片 ,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块.
-
在使用基于哈希分片的系统中,拥有”相近”片键的文档 很可能不会 存储在同一个数据块中,因此数据的分
离性更好一些. -
使用 nickname 作为片键,根据其值的哈希值进行数据分片
mongos> sh.shardCollection("articledb.comment",{"nickname":"hashed"}){"collectionsharded" : "articledb.comment","ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722526690, 7),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722526690, 3)
}
mongos> # 再次查看 分片副本集状态情况
mongos> sh.status()--- Sharding Status --- sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("66ab4772678657abc1742829")}shards:{ "_id" : "myshardrs01", "host" : "myshardrs01/172.18.30.110:27018,172.18.30.110:27118", "state" : 1, "topologyTime" : Timestamp(1722520733, 1) }{ "_id" : "myshardrs02", "host" : "myshardrs02/172.18.30.110:27318,172.18.30.110:27418", "state" : 1, "topologyTime" : Timestamp(1722520911, 2) }active mongoses:"5.0.28" : 1autosplit:Currently enabled: yesbalancer:Currently enabled: yesCurrently running: noFailed balancer rounds in last 5 attempts: 0Migration results for the last 24 hours: 512 : Successdatabases:{ "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("6e03e9c9-d824-493b-9809-ca48a9dad23d"), "timestamp" : Timestamp(1722526606, 1), "lastMod" : 1 } }articledb.commentshard key: { "nickname" : "hashed" }unique: falsebalancing: truechunks:myshardrs01 2myshardrs02 2{ "nickname" : { "$minKey" : 1 } } -->> { "nickname" : NumberLong("-4611686018427387902") } on : myshardrs01 Timestamp(1, 0) { "nickname" : NumberLong("-4611686018427387902") } -->> { "nickname" : NumberLong(0) } on : myshardrs01 Timestamp(1, 1) { "nickname" : NumberLong(0) } -->> { "nickname" : NumberLong("4611686018427387902") } on : myshardrs02 Timestamp(1, 2) { "nickname" : NumberLong("4611686018427387902") } -->> { "nickname" : { "$maxKey" : 1 } } on : myshardrs02 Timestamp(1, 3) { "_id" : "config", "primary" : "config", "partitioned" : true }config.system.sessionsshard key: { "_id" : 1 }unique: falsebalancing: truechunks:myshardrs01 512myshardrs02 512too many chunks to print, use verbose if you want to force print
mongos>
3、分片规则二:范围策略
-
对于 基于范围的分片 ,MongoDB按照片键的范围把数据分成不同部分.假设有一个数字的片键:想象一个
从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点.MongoDB把这条直线划分为更短的不
重叠的片段,并称之为 数据块 ,每个数据块包含了片键在一定范围内的数据. -
在使用片键做范围划分的系统中,拥有”相近”片键的文档很可能存储在同一个数据块中,因此也会存储在同
一个分片中. -
如使用作者年龄字段作为片键,按照点赞数的值进行分片:
mongos> sh.shardCollection("articledb.author",{"age":1}){"collectionsharded" : "articledb.author","ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1722527515, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1722527514, 3)
}# 再次查看 分片副本集状态情况
mongos> sh.status()
--- Sharding Status --- sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("66ab4772678657abc1742829")}shards:{ "_id" : "myshardrs01", "host" : "myshardrs01/172.18.30.110:27018,172.18.30.110:27118", "state" : 1, "topologyTime" : Timestamp(1722520733, 1) }{ "_id" : "myshardrs02", "host" : "myshardrs02/172.18.30.110:27318,172.18.30.110:27418", "state" : 1, "topologyTime" : Timestamp(1722520911, 2) }active mongoses:"5.0.28" : 1autosplit:Currently enabled: yesbalancer:Currently enabled: yesCurrently running: noFailed balancer rounds in last 5 attempts: 0Migration results for the last 24 hours: 512 : Successdatabases:{ "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("6e03e9c9-d824-493b-9809-ca48a9dad23d"), "timestamp" : Timestamp(1722526606, 1), "lastMod" : 1 } }articledb.authorshard key: { "age" : 1 }unique: falsebalancing: truechunks:myshardrs02 1{ "age" : { "$minKey" : 1 } } -->> { "age" : { "$maxKey" : 1 } } on : myshardrs02 Timestamp(1, 0) articledb.commentshard key: { "nickname" : "hashed" }unique: falsebalancing: truechunks:myshardrs01 2myshardrs02 2{ "nickname" : { "$minKey" : 1 } } -->> { "nickname" : NumberLong("-4611686018427387902") } on : myshardrs01 Timestamp(1, 0) { "nickname" : NumberLong("-4611686018427387902") } -->> { "nickname" : NumberLong(0) } on : myshardrs01 Timestamp(1, 1) { "nickname" : NumberLong(0) } -->> { "nickname" : NumberLong("4611686018427387902") } on : myshardrs02 Timestamp(1, 2) { "nickname" : NumberLong("4611686018427387902") } -->> { "nickname" : { "$maxKey" : 1 } } on : myshardrs02 Timestamp(1, 3) { "_id" : "config", "primary" : "config", "partitioned" : true }config.system.sessionsshard key: { "_id" : 1 }unique: falsebalancing: truechunks:myshardrs01 512myshardrs02 512too many chunks to print, use verbose if you want to force print
mongos>
4、注意的是:
1)一个集合只能指定一个片键,否则报错。
2)一旦对一个集合分片,分片键和分片值就不可改变。 如:不能给集合选择不同的分片键、不能更新
分片键的值。
3)根据age索引进行分配数据。
5、基于范围的分片方式与基于哈希的分片方式性能对比:
-
基于范围的分片方式提供了更高效的范围查询,给定一个片键的范围,分发路由可以很简单地确定哪个数
据块存储了请求需要的数据,并将请求转发到相应的分片中. -
不过,基于范围的分片会导致数据在不同分片上的不均衡,有时候,带来的消极作用会大于查询性能的积极
作用.比如,如果片键所在的字段是线性增长的,一定时间内的所有请求都会落到某个固定的数据块中,最终
导致分布在同一个分片中.在这种情况下,一小部分分片承载了集群大部分的数据,系统并不能很好地进行
扩展. -
与此相比,基于哈希的分片方式以范围查询性能的损失为代价,保证了集群中数据的均衡.哈希值的随机性
使数据随机分布在每个数据块中,因此也随机分布在不同分片中.但是也正由于随机性,一个范围查询很难
确定应该请求哪些分片,通常为了返回需要的结果,需要请求所有分片. -
如无特殊情况,一般推荐使用 Hash Sharding。
-
而使用 _id 作为片键是一个不错的选择,因为它是必有的,你可以使用数据文档 _id 的哈希作为片键。
这个方案能够是的读和写都能够平均分布,并且它能够保证每个文档都有不同的片键所以数据块能够很
精细。 -
似乎还是不够完美,因为这样的话对多个文档的查询必将命中所有的分片。虽说如此,这也是一种比较
好的方案了。 -
理想化的 shard key 可以让 documents 均匀地在集群中分布:
6、显示集群的详细信息:
mongos> db.printShardingStatus()
7、查看均衡器是否工作(需要重新均衡时系统才会自动启动,不用管它):
mongos> sh.isBalancerRunning()
8、查看当前 Balancer 状态:
mongos> sh.getBalancerState()
9、分片后插入数据测试—测试一(哈希规则)
9.1、登录 mongos 后,向 comment 循环插入1000条数据做测试:
# 进入路由分片节点 终端,插入数据。mongos> use articledb
switched to db articledbmongos> for(var i=1;i<=1000;i++){db.comment.insert({_id:i+"",nickname:"BoBo"+i})}
WriteResult({ "nInserted" : 1 })mongos> db.comment.count()
1000
提示: js 的语法,因为 mongo 的 shell 是一个 JavaScript 的 shell。
注意:从路由上插入的数据,必须包含片键,否则无法插入。
9.2、分别登陆两个片的主节点,统计文档数量
# 打开一终端,查看节点信息# 切换目录
cd /usr/local/mongodb/# 连接 第一套 分片副本集 的 MongoDB 服务 主节点
root@WIN-20240529BJA:/usr/local/mongodb# /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27018myshardrs01:PRIMARY> use articledb
switched to db articledb
myshardrs01:PRIMARY> db.comment.count()
507# 打开另一终端,查看节点信息# 切换目录
cd /usr/local/mongodb/# 连接 第二套 分片副本集 的 MongoDB 服务 的主节点
root@WIN-20240529BJA:/usr/local/mongodb# /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27318myshardrs02:PRIMARY> use articledb
switched to db articledb
myshardrs02:PRIMARY> db.comment.count()
493
10、分片后插入数据测试—测试二(范围规则)
10.1、登录 mongs 后,向 comment 循环插入 20000 条数据做测试:
# 进入路由分片节点 终端,插入数据。# 先修改 数据块尺寸(chunksize)为 1M,方便测试
mongos> use config
mongos> db.settings.save( { _id:"chunksize", value: 1 } )
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "chunksize" })
mongos> mongos> use articledb
switched to db articledb# 插入 20000 条数据(有点慢)
mongos> for(var i=1;i<=20000;i++){db.author.save({"name": "BoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBo"+i, "age": NumberInt(i%120)})}
WriteResult({ "nInserted" : 1 })mongos> db.author.count()
20000# 插入成功后,仍然要分别查看两个分片副本集的数据情况。分片效果# 打开一终端,# 切换目录
cd /usr/local/mongodb/# 连接 第一套 分片副本集 的 MongoDB 服务 主节点
root@WIN-20240529BJA:/usr/local/mongodb# /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27018myshardrs01:PRIMARY> use articledb
switched to db articledb
myshardrs01:PRIMARY> db.author.count()
0
myshardrs01:PRIMARY> db.author.count()
0
myshardrs01:PRIMARY> db.author.count()
0
myshardrs01:PRIMARY> db.author.count()
0
myshardrs01:PRIMARY> db.author.count()
131
myshardrs01:PRIMARY> db.author.count()
157
myshardrs01:PRIMARY> db.author.count()
166# 打开另一终端# 切换目录
cd /usr/local/mongodb/# 连接 第二套 分片副本集 的 MongoDB 服务 的主节点
root@WIN-20240529BJA:/usr/local/mongodb# /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27318myshardrs02:PRIMARY> use articledb
switched to db articledb
myshardrs02:PRIMARY> db.comment.count()
493
myshardrs02:PRIMARY> db.author.count()
5310
myshardrs02:PRIMARY> db.author.count()
5785
myshardrs02:PRIMARY> db.author.count()
8350
myshardrs02:PRIMARY> db.author.count()
10189
myshardrs02:PRIMARY> db.author.count()
15654
myshardrs02:PRIMARY> db.author.count()
18812
myshardrs02:PRIMARY> db.author.count()
19952
10.2、提示:如果查看状态发现没有分片,则可能是由于以下原因造成了:
1)系统繁忙,正在分片中。
2)数据块(chunk)没有填满,默认的数据块尺寸(chunksize)是64M,填满后才会考虑向其他片的
数据块填充数据,因此,为了测试,可以将其改小,这里改为1M,操作如下:
use config
db.settings.save( { _id:"chunksize", value: 1 } )
3)测试完改回来:
use config
db.settings.save( { _id:"chunksize", value: 64 } )
4)注意:
要先改小,再设置分片。为了测试,可以先删除集合,重新建立集合的分片策略,再插入数据测试即可。
四、mongodb 再增加一个路由节点
1、mongodb 再增加一个路由节点 mongos02 :第一步:准备存放数据和日志的目录:
#-----------mongos01mkdir -p /usr/local/mongodb/sharded_cluster/mymongos_27117/log
2、mongodb 再增加一个路由节点 mongos02 :第二步:新建或修改配置文件(mymongos_27117节点):
vim /usr/local/mongodb/sharded_cluster/mymongos_27117/mongos.conf# mymongos_27117 内容如下(注意 yaml 文件格式):systemLog:# MongoDB发送所有日志输出的目标指定为文件destination: file# mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.log"# 当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾logAppend: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll: true#服务实例绑定的IPbindIp: localhost,172.18.30.110# bindip# 绑定的端口port: 27117
sharding:#指定配置节点副本集configDB: myconfigrs/172.18.30.110:27019,172.18.30.110:27119,172.18.30.110:27219
3、mongodb 再增加一个路由节点 mongos02 :第三步:启动 mongos 服务::
# 切换目录
cd /usr/local/mongodb/# 启动 MongoDB 服务
[root@WIN-20240529BJA:/usr/local/mongodb#] /usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27117/mongos.conf# 查看进程,mongodb 是否启动成功
[root@WIN-20240529BJA:/usr/local/mongodb#] ps -ef | grep mongod# 使用mongo客户端登录27117,发现,第二个路由无需配置,因为分片配置都保存到了配置服务器中
了。
五、mongodb compass & springData 连接测试
1、 Compass 连接分片集群
1) Compass 连接 第一个路由测试
2) Compass 连接 第二个路由 测试
3)提示:和连接单机 mongod一样。连接成功后,上方有 mongos 和分片集群的提示。
2、SpringDataMongDB 连接分片集群
Java客户端常用的是SpringDataMongoDB,其连接的是mongs路由,配置和单机mongod的配置是一
样的。
1)多个路由的时候的SpringDataMongoDB的客户端配置参考如下:
# article-mongodb\src\main\resources\application.ymlspring:# 数据源配置data:mongodb:# # 主机地址# host: 172.18.30.110# # 数据库# database: articledb# # 默认端口27017# port: 27017# # 也可以使用uri连接# # uri mongodb //172.18.30.110:27017/articledb# uri: mongodb://172.18.30.110:27017,172.18.30.110:27018,172.18.30.110:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrsuri: mongodb://172.18.30.110:27017,172.18.30.110:27117/articledb
2)通过日志发现,写入数据的时候,会选择一个路由写入:
3、清除所有的节点数据(备用)
如果在搭建分片的时候有操作失败或配置有问题,需要重新来过的,可以进行如下操作:
3.1、第一步:查询出所有的测试服务节点的进程:
# 查看 mongodb 进程
[root@WIN-20240529BJA:/usr/local/mongodb#] ps -ef | grep mongod# 根据上述的进程编号,依次中断进程:
kill -2 进程PID
3.2、第二步:清除所有的节点的数据:
rm -rf /usr/local/mongodb/sharded_cluster/myconfigrs_27019/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myconfigrs_27119/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myconfigrs_27219/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs01_27018/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs01_27118/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs01_27218/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs02_27318/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs02_27418/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/myshardrs02_27518/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/mymongos_27017/data/db/*.* \ &
rm -rf /usr/local/mongodb/sharded_cluster/mymongos_27117/data/db/*.*
3.3、第三步:查看或修改有问题的配置
vim /usr/local/mongodb/sharded_cluster/mymongos_27117/mongos.conf# mymongos_27117 内容如下(注意 yaml 文件格式):systemLog:# MongoDB发送所有日志输出的目标指定为文件destination: file# mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.log"# 当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾logAppend: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll: true#服务实例绑定的IPbindIp: localhost,172.18.30.110# bindip# 绑定的端口port: 27117
sharding:#指定配置节点副本集configDB: myconfigrs/172.18.30.110:27019,172.18.30.110:27119,172.18.30.110:27219
3.4、第四步:依次启动所有节点,不包括路由节点:
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs01_27018/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs01_27118/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs01_27218/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs02_27318/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs02_27418/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myshardrs02_27518/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myconfigrs_27019/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myconfigrs_27119/mongod.conf
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongod -f
/mongodb/sharded_cluster/myconfigrs_27219/mongod.conf
3.5、第五步:对两个数据分片副本集和一个配置副本集进行初始化和相关配置
# 使用客户端命令连接任意一个节点,但这里尽量要连接主节点
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27018# 执行初始化副本集命令
> rs.initiate()# 查看副本集情况(节选内容):
myshardrs01:SECONDARY> rs.status()# 主节点配置查看
myshardrs01:PRIMARY> rs.conf()# 添加副本节点:
myshardrs01:PRIMARY> rs.add("172.18.30.110:27118")# 添加仲裁从节点
myshardrs01:PRIMARY> rs.addArb("172.18.30.110:27218")
3.6、第六步:检查路由 mongos 的配置,并启动 mongos 服务
/usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27017/mongos.conf
3.7、第七步:mongo 登录 mongos,在其上进行相关操作。
usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27017
上一节关联文档请点击
# mongodb_基础到进阶 – MongoDB 高级–MongoDB 集群部署与安全性(三)