目录
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
# 日志设置 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
# 日志设置 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
# 日志设置 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
# 日志设置 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