# mongodb_基础到进阶 -- MongoDB 高级--MongoDB 集群部署与安全性(四)

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 集群部署与安全性(三)

相关推荐
Ai 编码助手1 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
陈燚_重生之又为程序员1 小时前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle2 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻2 小时前
MySQL排序查询
数据库·mysql
萧鼎2 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
^velpro^2 小时前
数据库连接池的创建
java·开发语言·数据库
荒川之神2 小时前
ORACLE _11G_R2_ASM 常用命令
数据库·oracle
IT培训中心-竺老师2 小时前
Oracle 23AI创建示例库
数据库·oracle
小白学大数据2 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
time never ceases2 小时前
使用docker方式进行Oracle数据库的物理迁移(helowin/oracle_11g)
数据库·docker·oracle