目录


1. 概述


2. 使用场景


3. 优缺点


4. 节点作用


5. 部署规划


6. 内存配额


7. 配置文件


8. 配置集群分片


9. 开启认证


10. 集群验证


11. 总结


概述


MongoDB 集群分片是一种水平扩展数据库的方法,通过将数据分布在多个物理服务器上,提高系统的性能和可扩展性。

分片的核心思想是将数据分成多个部分(称为“分片”),每个分片存储在不同的服务器上,从而分散负载,提高查询和写入性能。


使用场景


大规模数据存储:当单个 MongoDB 实例无法处理大量数据时,可以使用分片来分布数据,提高存储容量。


高并发访问:在高并发读写场景下,分片可以分散负载,提高系统的响应速度和吞吐量。


地理分布:当数据需要在全球范围内访问时,分片可以将数据分布到不同的地理位置,减少网络延迟。


实时分析:在需要实时处理大量数据的场景下,分片可以提高查询性能,支持实时分析和报表生成。


优缺点


优点


高可扩展性:通过增加更多的分片服务器,可以轻松扩展存储和计算能力。


高可用性:每个分片可以配置为副本集,提供数据冗余和故障恢复能力。


负载均衡:数据和查询负载可以均匀分布在多个分片上,提高整体性能。


灵活的数据分布:可以根据业务需求选择合适的分片键,优化数据分布和查询性能。


缺点


复杂性:分片架构比单实例架构更复杂,需要更多的管理和维护工作。


配置和管理成本:需要配置路由服务器、配置服务器和分片服务器,增加了初始设置和运维成本。


数据迁移:在分片键选择不当或数据增长过快时,可能需要重新平衡数据,导致额外的开销。


查询性能:跨分片的聚合查询和联合查询可能会影响性能,需要优化查询策略。


节点作用


mongos(路由服务器)


作用:作为客户端应用程序和分片集群之间的接口,负责路由查询和写入操作到正确的分片。


特点:无状态,可以横向扩展,提高系统的并发处理能力。


shard(分片服务器)


作用:存储实际的数据,每个分片可以是一个独立的 MongoDB 实例或副本集。


特点:数据分布在多个分片上,每个分片负责一部分数据,提高存储和查询性能。


config server(配置服务器)


作用:存储集群的元数据信息,如分片键、分片分布、路由信息等。


特点:通常使用副本集形式部署,确保高可用性和数据冗余。


下载地址


https://www.mongodb.com/try/download/community


配置hosts解下

vim /etc/hosts
10.10.10.21 mon1
10.10.10.22 mon2
10.10.10.23 mon3


集群规划

10.10.10.21 mon1:mongos(30000)\config(27017-主)\shard1(40001-主)\shard2(40002-从)\shard3(40003-从)
10.10.10.22 mon2:mongos(30000)\config(27017-从)\shard1(40001-从)\shard2(40002-主)\shard3(40003-从)
10.10.10.23 mon3:mongos(30000)\config(27017-从)\shard1(40001-从)\shard2(40002-从)\shard3(40003-主)
 
 
3台机,每台机5个组件,分别mongos 1 个,config server 1 个,shard server 3 个


部署

解压(三台机器)

mongosh:
wget https://downloads.mongodb.com/compass/mongosh-2.3.1-linux-x64.tgz
tar xvf mongosh-2.3.1-linux-x64.tgz
mongodb:
tar xvf mongodb-linux-x86_64-rhel70-7.0.14.tgz
mv  mongodb-linux-x86_64-rhel70-7.0.14 mongodb

创建相关目录(三台机器)

[root@easyliao012 monogocluster]# mkdir -p /monogocluster/shard{1,2,3}/{config,log,data}
[root@easyliao012 monogocluster]#mkdir -p /monogocluster/mongos/{config,log,data}
[root@easyliao012 monogocluster]# mkdir -p /monogocluster/config/{config,log,data}


内存配置


shard 和 config 服务器的 WiredTiger 缓存大小的分配建议:


1. Shard 服务器的缓存大小分配:


对于每个 Shard 服务器,可以根据数据量和预计的工作负载来调整缓存大小。一般来说,将缓存大小设置为机器内存的 50%-75% 是

比较常见的做法。


例如,如果你的Shard服务器有16GB的内存,可以将缓存大小设置为8GB-12GB,即 wiredTiger.engineConfig.cacheSizeGB:8


或者wiredTiger.engineConfig.cacheSizeGB:12。


这样可以让MongoDB利用一部分内存来缓存数据和索引,提高读取操作的性能


2. Config 服务器的缓存大小分配:


Config 服务器主要用于存储集群的元数据信息,相对来说对内存的需求较小。通常可以将缓存大小设置为机器内存的 25%-50%。


例如,如果你的 Config 服务器有 8GB 的内存,可以将缓存大小设置为 2GB - 4GB,即 wiredTiger.engineConfig.cacheSizeGB: 2 


或者 wiredTiger.engineConfig.cacheSizeGB: 4。


需要注意的是,缓存大小的分配应该综合考虑系统内存大小、数据量、查询模式等因素,以达到最佳性能和资源利用的平衡点。


配置集群分片配置文件


配置文件config(三台机器)


vim /monogocluster/config/config/mongo-conf

# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/config/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen
 
 
# 网络设置
net:
  port: 27017                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制
 
 
# 数据目录
storage:
  dbPath: /monogocluster/config/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 3               # 根据情况配置内存  
 
 
# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/config/data/mongod.pid # PID 文件路径 
 
 
#复制集名称  
replication:
  replSetName: "mgconfig"
 
 
#作为配置服务  
sharding:
  clusterRole: configsvr

配置文件mongos(三台机器)

vim /monogocluster/mongos/config/mongo-conf

# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/mongos/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen
 
 
# 网络设置
net:
  port: 30000                    # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制
 
 
# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/mongos/data/mongod.pid # PID 文件路径 
 
 
#网络延迟阈值  
replication:
  localPingThresholdMs: 15
 
 
#关联配置服务
sharding:
  configDB: mgconfig/mon1:27017,mon2:27017,mon3:27017


配置文件mongoshard1(三台机器)

vim /monogocluster/shard1/config/mongo-conf

# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard1/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen
 
 
# 网络设置
net:
  port: 40001                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制
 
 
# 数据目录
storage:
  dbPath: /monogocluster/shard1/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 
 
 
# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard1/data/mongod.pid # PID 文件路径 
 
 
#复制集名称
replication:
  replSetName: "shard1"
 
 
#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"
 
 
#作为分片服务
sharding:
  clusterRole: shardsvr


配置文件mongoshard2(三台机器)

vim /monogocluster/shard2/config/mongo-conf

# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard2/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen
 
 
# 网络设置
net:
  port: 40002                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制
 
 
# 数据目录
storage:
  dbPath: /monogocluster/shard2/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 
 
 
# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard2/data/mongod.pid # PID 文件路径 
 
 
#复制集名称
replication:
  replSetName: "shard2"
 
 
#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"
 
 
#作为分片服务
sharding:
  clusterRole: shardsvr


配置文件mongoshard3(三台机器)

vim /monogocluster/shard3/config/mongo-conf

# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard3/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen
 
 
# 网络设置
net:
  port: 40003                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制
 
 
# 数据目录
storage:
  dbPath: /monogocluster/shard3/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 
 
 
# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard3/data/mongod.pid # PID 文件路径 
 
 
#复制集名称
replication:
  replSetName: "shard3"
 
 
#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"
 
 
#作为分片服务
sharding:
  clusterRole: shardsvr


启动config服务并配置复制集(3台机器执行相同操作)

/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf
 
 
连接一个config实例
mongosh mongodb://easyliao012:27017
初始化复制集
这个 mgconfig 名字一定要和config 配置文件中 replSet 的名字一致
 
 
config={_id:"mgconfig",members:[ 
{_id:0,host:"mon1:27017"}, 
{_id:1,host:"mon2:27017"}, 
{_id:2,host:"mon3:27017"}, 
]};
 
 
rs.initiate(config)
rs.status()


启动shard分片并配置副本集

---shard1
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf
##配置副本集
权重越高priority:3会被指定为主节点
连接任意一个shard1实例
[root@mysql1 bin]# mongosh mongodb://mon1:40001
创建复制集
use admin 
 
 
config={_id:"shard1",members:[ 
{_id:0,host:"mon1:40001",priority:3}, 
{_id:1,host:"mon2:40001",priority:1}, 
{_id:2,host:"mon3:40001",priority:1}, 
]}
 
 
rs.initiate(config)
rs.status()
 
 
--shard2
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf
##配置副本集
连接任意一个shard2实例
[root@mysql1 bin]# mongosh mongodb://mon2:40002
创建复制集
use admin 
 
 
config={_id:"shard2",members:[ 
{_id:0,host:"mon1:40002",priority:1}, 
{_id:1,host:"mon2:40002",priority:3}, 
{_id:2,host:"mon3:40002",priority:1}, 
]}
 
 
rs.initiate(config)
rs.status()
 
 
---shard3
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf
##配置副本集
连接任意一个shard3实例
[root@mysql1 bin]# mongosh mongodb://mon3:40003
创建复制集
use admin 
 
 
config={_id:"shard3",members:[ 
{_id:0,host:"mon1:40003",priority:1}, 
{_id:1,host:"mon2:40003",priority:1}, 
{_id:2,host:"mon3:40003",priority:3}, 
]};
 
 
rs.initiate(config)
rs.status()


启动mongos并添加分片

##启动
 /opt/mongodb/bin/mongos --config /monogocluster/mongos/config/mongo-conf 
 
 
##登陆路由节点
mongosh mongodb://mon1:30000
use admin
##添加分片
sh.addShard("shard1/mon1:40001,mon2:40001,mon3:40001") 
sh.addShard("shard2/mon1:40002,mon2:40002,mon3:40002")
sh.addShard("shard3/mon1:40003,mon2:40003,mon3:40003")
##查看状态
[direct: mongos] admin> sh.status();
shardingVersion
{ _id: 1, clusterId: ObjectId("66f50c31e8f91dc6de9b9770") }
---
shards
[
  {
    _id: 'shard1',
    host: 'shard1/mon1:40001,mon2:40001,mon3:40001',
    state: 1,
    topologyTime: Timestamp({ t: 1727338491, i: 3 })
  },
  {
    _id: 'shard2',
    host: 'shard2/mon1:40002,mon2:40002,mon3:40002',
    state: 1,
    topologyTime: Timestamp({ t: 1727338512, i: 1 })
  },
  {
    _id: 'shard3',
    host: 'shard3/mon1:40003,mon2:40003,mon3:40003',
    state: 1,
    topologyTime: Timestamp({ t: 1727338518, i: 3 })
  }
]
---
active mongoses
[ { '7.0.14': 3 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{ 'Currently enabled': 'yes', 'Currently running': 'no' }
---
databases
[
  {
    database: { _id: 'config', primary: 'config', partitioned: true },
    collections: {}
  }
]


创建账户

##在mongos创建一个管理员账户用于数据库操作,
mongosh mongodb://mon1:30000
mongos>use admin
mongos>db.createUser({user:"root",pwd:"sdhjfREWFWEF23e",roles:["root"]})
mongos>db.auth("root","sdhjfREWFWEF23e") 
 
 
##在shard1、shard2、shard3分别创建副本集管理员账户,每个分片都要创建主节点上
mongosh mongodb://mon1:40001
mongosh mongodb://mon2:40002
mongosh mongodb://mon3:40003
mongos>use admin
mongos>db.createUser({user:"root",pwd:"sdhjfREWFWEF23e",roles:["root"]})
mongos>db.auth("root","sdhjfREWFWEF23e")


安全认证

##创建秘钥文件
openssl rand -base64 753 >/monogocluster/config/mongo-keyfile
#将主节点生成的mongo-keyfile文件拷贝到其他服务器目录,注意权限
chmod 600 /monogocluster/config/mongo-keyfile
##拷贝秘钥
root@mysql1 bin]# scp keyFile.key mongodb@mon2:/monogocluster/config/
root@mysql1 bin]# scp keyFile.key mongodb@mon3:/monogocluster/config/

修改config server,shard1,shard2,shard3配置文件,增加如下参数:
security:
  authorization: "enabled"
  keyFile: /monogocluster/config/mongo-keyfile
 
 
修改mongos 配置文件,增加如下参数:
security:
  keyFile: /monogocluster/config/mongo-keyfile


关闭服务

关闭集群
第一步:关闭所有mongos路由实例
第二步:关闭所有分片
第三步:关闭所有的配置服务器
 
 
##关闭mongos
mongosh mongodb://127.0.0.1:30000
use admin
db.auth('root','sdhjfREWFWEF23e')
db.shutdownServer()
 
 
##关闭分片
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf --shutdown
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf  --shutdown
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf  --shutdown
 
 
##关闭configservers
/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf --shutdown


启动服务

启动集群
 第一步:启动配置服务器
 第二步:启动所有分片
 第三步:启动mongos路由实例
 
 
##启动配置服务
/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf
 
 
##启动所有分片
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf 
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf 
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf
 
 
## 启动mongos路由实例
/opt/mongodb/bin/mongos --config /monogocluster/mongos/config/mongo-conf


验证数据库

--- 测试服务器分片功能
mongosh mongodb://127.0.0.1:30000
[direct: mongos] test> use admin
[direct: mongos] admin> db.auth('root','sdhjfREWFWEF23e')
--- 启用数据库分片
sh.enableSharding("db2")
--- 启用表分片
sh.shardCollection("db2.user",{"id":1})
sh.shardCollection("db2.user1",{"id":"hashed"})
--- 模拟写入数据
在db2库的user表中循环写入数据
use db2
for(i=1;i<=600;i++){db.tyuser3.insert({"id":i,"name":"ty"+i})}
 
 
---查看集群情况
[direct: mongos] db2> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId("66f50c31e8f91dc6de9b9770") }
shards
[{
    _id: 'shard1',
    host: 'shard1/mon1:40001,mon2:40001,mon3:40001',
    state: 1,
    topologyTime: Timestamp({ t: 1727338491, i: 3 })
  },{
    _id: 'shard2',
    host: 'shard2/mon1:40002,mon2:40002,mon3:40002',
    state: 1,
    topologyTime: Timestamp({ t: 1727338512, i: 1 })
  },{
    _id: 'shard3',
    host: 'shard3/mon1:40003,mon2:40003,mon3:40003',
    state: 1,
    topologyTime: Timestamp({ t: 1727338518, i: 3 })
  }]
active mongoses
[ { '7.0.14': 3 } ]
 
 
 
 
---查看集合分片情况
var dbName = "db2"; 
db.getSiblingDB(dbName).getCollectionNames().forEach(function(collName) {
    print("————————————————————————"); 
    print("Collection: " + collName); 
    db.getSiblingDB(dbName).getCollection(collName).getShardDistribution();
});
 
 
输出结果
————————————————————————
Collection: user1
Shard shard1 at shard1/mon1:40001,mon2:40001,mon3:40001
 data : 9KiB docs : 214 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity
 
 
Shard shard3 at shard3/mon1:40003,mon2:40003,mon3:40003
 data : 7KiB docs : 175 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity
 
 
Shard shard2 at shard2/mon1:40002,mon2:40002,mon3:40002
 data : 9KiB docs : 211 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity
 
 
Totals
 data : 26KiB docs : 600 chunks : 0
 Shard shard1 contains 35.64% data, 35.66% docs in cluster, avg obj size on shard : 45B
 Shard shard3 contains 29.19% data, 29.16% docs in cluster, avg obj size on shard : 45B
 Shard shard2 contains 35.16% data, 35.16% docs in cluster, avg obj size on shard : 45B
————————————————————————
Collection: user
Shard shard3 at shard3/mon1:40003,mon2:40003,mon3:40003
 data : 26KiB docs : 600 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity
 
 
Totals
 data : 26KiB docs : 600 chunks : 0
 Shard shard3 contains 100% data, 100% docs in cluster, avg obj size on shard : 45B


总结


MongoDB 集群分片是一种强大的水平扩展解决方案,适用于大规模数据存储和高并发访问场景。通过将数据分布在多个物理服务器上,

分片可以显著提高系统的性能和可扩展性。然而,分片架构的复杂性和管理成本也需要仔细考虑。在选择分片键和配置集群时,

应根据业务需求和数据特性进行优化,以充分发挥分片的优势。



来源:https://blog.csdn.net/qq_34692500/article/details/142784842