mongodb_基础到进阶 -- MongoDB 高级--MongoDB 集群部署与安全性(四)
一、mongodb 第一个路由节点创建
1、分片集群架构目标
两个分片节点副本集(3+3)+一个配置节点副本集(3)+两个路由节点(2),共11个服务节点。
2、mongodb 第一个路由节点创建:第一步:准备存放数据和日志的目录:
java
#-----------mongos01
mkdir -p /usr/local/mongodb/sharded_cluster/mymongos_27017/log
3、mongodb 第一个路由节点创建::第二步:新建或修改配置文件(mymongos_27017节点):
java
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将写入其PID
pidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27017/log/mongod.pid"
net:
#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 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 服务::
java
# 切换目录
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 mongod
root 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
java
# 切换目录
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 27017
mongos> show dbs
admin 0.000GB
config 0.000GB
mongos> use mongotest
switched to db mongotest
mongos> 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 配置文件参考::
java
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、使用命令添加分片:添加分片 语法:
java
sh.addShard("IP:Port")
2、将第一套分片副本集添加进来
java
# 打开另一终端,查看节点信息
# 切换目录
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 )
java
# 切换目录
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 节点 查看 分片副本集状态情况
java
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" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: yes
Collections 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: 0
Migration results for the last 24 hours:
29 : Success
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
myshardrs01 995
myshardrs02 29
too many chunks to print, use verbose if you want to force print
mongos>
5、提示:如果添加分片失败,需要先手动移除分片,检查添加分片的信息的正确性后,再次添加分片。
1)移除分片参考:
java
use admin
db.runCommand( { removeShard: "myshardrs02" } )
2)注意:如果只剩下最后一个 shard,是无法删除的,移除时会自动转移分片数据,需要一个时间过程。
完成后,再次执行删除分片命令才能真正删除。
6、开启分片功能:sh.enableSharding("库名")、sh.shardCollection("库名.集合名",{"key":1})
在 mongos 上的 articledb 数据库配置 sharding:
java
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)语法:
java
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 作为片键,根据其值的哈希值进行数据分片
java
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" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration results for the last 24 hours:
512 : Success
databases:
{ "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("6e03e9c9-d824-493b-9809-ca48a9dad23d"), "timestamp" : Timestamp(1722526606, 1), "lastMod" : 1 } }
articledb.comment
shard key: { "nickname" : "hashed" }
unique: false
balancing: true
chunks:
myshardrs01 2
myshardrs02 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.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
myshardrs01 512
myshardrs02 512
too many chunks to print, use verbose if you want to force print
mongos>
3、分片规则二:范围策略
-
对于 基于范围的分片 ,MongoDB按照片键的范围把数据分成不同部分.假设有一个数字的片键:想象一个
从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点.MongoDB把这条直线划分为更短的不
重叠的片段,并称之为 数据块 ,每个数据块包含了片键在一定范围内的数据.
-
在使用片键做范围划分的系统中,拥有"相近"片键的文档很可能存储在同一个数据块中,因此也会存储在同
一个分片中.
-
如使用作者年龄字段作为片键,按照点赞数的值进行分片:
java
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" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration results for the last 24 hours:
512 : Success
databases:
{ "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("6e03e9c9-d824-493b-9809-ca48a9dad23d"), "timestamp" : Timestamp(1722526606, 1), "lastMod" : 1 } }
articledb.author
shard key: { "age" : 1 }
unique: false
balancing: true
chunks:
myshardrs02 1
{ "age" : { "$minKey" : 1 } } -->> { "age" : { "$maxKey" : 1 } } on : myshardrs02 Timestamp(1, 0)
articledb.comment
shard key: { "nickname" : "hashed" }
unique: false
balancing: true
chunks:
myshardrs01 2
myshardrs02 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.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
myshardrs01 512
myshardrs02 512
too 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、显示集群的详细信息:
java
mongos> db.printShardingStatus()
7、查看均衡器是否工作(需要重新均衡时系统才会自动启动,不用管它):
java
mongos> sh.isBalancerRunning()
8、查看当前 Balancer 状态:
java
mongos> sh.getBalancerState()
9、分片后插入数据测试---测试一(哈希规则)
9.1、登录 mongos 后,向 comment 循环插入1000条数据做测试:
java
# 进入路由分片节点 终端,插入数据。
mongos> use articledb
switched to db articledb
mongos> 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、分别登陆两个片的主节点,统计文档数量
java
# 打开一终端,查看节点信息
# 切换目录
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> 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 27318
myshardrs02:PRIMARY> use articledb
switched to db articledb
myshardrs02:PRIMARY> db.comment.count()
493
10、分片后插入数据测试---测试二(范围规则)
10.1、登录 mongs 后,向 comment 循环插入 20000 条数据做测试:
java
# 进入路由分片节点 终端,插入数据。
# 先修改 数据块尺寸(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 27018
myshardrs01: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 27318
myshardrs02: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,操作如下:
java
use config
db.settings.save( { _id:"chunksize", value: 1 } )
3)测试完改回来:
java
use config
db.settings.save( { _id:"chunksize", value: 64 } )
4)注意:
要先改小,再设置分片。为了测试,可以先删除集合,重新建立集合的分片策略,再插入数据测试即可。
四、mongodb 再增加一个路由节点
1、mongodb 再增加一个路由节点 mongos02 :第一步:准备存放数据和日志的目录:
java
#-----------mongos01
mkdir -p /usr/local/mongodb/sharded_cluster/mymongos_27117/log
2、mongodb 再增加一个路由节点 mongos02 :第二步:新建或修改配置文件(mymongos_27117节点):
java
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将写入其PID
pidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:
#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 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 服务::
java
# 切换目录
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的客户端配置参考如下:
java
# article-mongodb\src\main\resources\application.yml
spring:
# 数据源配置
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=myrs
uri: mongodb://172.18.30.110:27017,172.18.30.110:27117/articledb
2)通过日志发现,写入数据的时候,会选择一个路由写入:
3、清除所有的节点数据(备用)
如果在搭建分片的时候有操作失败或配置有问题,需要重新来过的,可以进行如下操作:
3.1、第一步:查询出所有的测试服务节点的进程:
java
# 查看 mongodb 进程
[root@WIN-20240529BJA:/usr/local/mongodb#] ps -ef | grep mongod
# 根据上述的进程编号,依次中断进程:
kill -2 进程PID
3.2、第二步:清除所有的节点的数据:
java
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、第三步:查看或修改有问题的配置
java
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将写入其PID
pidFilePath: "/usr/local/mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:
#服务实例绑定的IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 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、第四步:依次启动所有节点,不包括路由节点:
java
/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、第五步:对两个数据分片副本集和一个配置副本集进行初始化和相关配置
java
# 使用客户端命令连接任意一个节点,但这里尽量要连接主节点
/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 服务
java
/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,在其上进行相关操作。
java
usr/local/mongodb/mongodb-linux-x86_64-ubuntu1804-5.0.28/bin/mongo --host 172.18.30.110 --port 27017
上一节关联文档请点击
# mongodb_基础到进阶 -- MongoDB 高级--MongoDB 集群部署与安全性(三)