Ubuntu 上实现 MongoDB 负载均衡的两种常用方案
- 副本集读写分离:在同一副本集内,写操作集中在 Primary,读操作可分发到多个 Secondary,实现读负载均衡与高可用。适用于单集群容量足够但并发读多、写相对可控的场景。
- 分片集群:将数据按 分片键 分布到多个 Shard(每个 Shard 通常是一个副本集),由 mongos 路由请求,实现写入与存储的水平扩展。适用于数据量大、写入吞吐高或未来有显著增长预期的场景。
方案一 副本集读写分离实现负载均衡
- 安装 MongoDB(Ubuntu 20.04 示例,其他版本替换仓库即可)
- 导入公钥并添加仓库:
- wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
- echo “deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse” | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
- sudo apt-get update && sudo apt-get install -y mongodb-org
- 配置副本集(三节点示例:node1、node2、node3)
- 编辑各节点配置文件 /etc/mongod.conf:
- storage.dbPath、systemLog、net.port、net.bindIp(建议绑定内网 IP)
- replication.replSetName: “rs0”
- 启动服务:sudo systemctl start mongod && sudo systemctl enable mongod
- 初始化副本集
- mongo --host node1 --port 27017
- 执行:
- rs.initiate({
_id: “rs0”,
members: [
{ _id: 0, host: “node1:27017” },
{ _id: 1, host: “node2:27017” },
{ _id: 2, host: “node3:27017” }
]
})
- 验证与读负载均衡
- rs.status() 查看 PRIMARY/SECONDARY 状态
- 在连接字符串中启用读偏好:mongodb://node1,node2,node3:27017/db?replicaSet=rs0&readPreference=secondaryPreferred
- 说明:读请求将被分发到 Secondary,写请求仍在 Primary;如需强一致读,使用 primary 或 majority。
方案二 分片集群实现水平扩展与负载均衡
- 组件与端口规划
- Config Servers(CSRS):至少 3 个,建议以副本集部署,端口 27019
- Shard:每个 Shard 为副本集,示例端口 27018
- mongos:路由入口,端口 27017
- 部署步骤
- 启动配置服务器副本集(CSRS)
- 配置 /etc/mongod.conf(clusterRole: configsvr,replSetName: configReplSet)
- 启动后连接任一 CSRS 节点初始化:
- rs.initiate({
_id: “configReplSet”,
configsvr: true,
members: [
{ _id: 0, host: “cfg1:27019” },
{ _id: 1, host: “cfg2:27019” },
{ _id: 2, host: “cfg3:27019” }
]
})
- 启动分片(每个分片为副本集)
- 配置 /etc/mongod.conf(clusterRole: shard,replSetName: shardX)
- 启动后在各分片内 rs.initiate(…) 完成副本集初始化
- 启动 mongos
- 配置 /etc/mongos.conf:sharding.configDB: configReplSet/cfg1:27019,cfg2:27019,cfg3:27019
- 启动:sudo systemctl start mongos
- 添加分片到集群
- mongo --host mongos_host --port 27017
- sh.addShard(“shard1/nodeA:27018,nodeB:27018,nodeC:27018”)
- sh.addShard(“shard2/nodeD:27018,nodeE:27018,nodeF:27018”)
- 启用数据库与集合分片
- sh.enableSharding(“yourDatabase”)
- sh.shardCollection(“yourDatabase.yourCollection”, { “shardKey”: 1 })
- 验证
- sh.status() 查看分片与 chunk 分布
- 说明
- 客户端直连 mongos(端口 27017),由 mongos 将读写请求路由到对应分片;数据按 shardKey 分布,实现写入与存储的水平扩展与负载均衡。
关键配置与运维要点
- 分片键设计
- 选择高基数、写入频繁且常用于查询条件的字段;避免单调递增键导致热点;结合 hashed sharding 或 range sharding 评估吞吐与均衡性。
- 读偏好与一致性
- 副本集读负载均衡通过 readPreference 控制:secondaryPreferred 提升读吞吐;对强一致使用 primary/majority。
- 安全与网络
- 仅开放必要端口(如 27017/27018/27019),限制来源网段;开启鉴权(SCRAM 或 x.509),为管理员与业务账户分配最小权限。
- 监控与备份
- 使用 MongoDB Atlas/Ops Manager 或第三方监控,关注 connections、opcounters、repl lag、balancer 状态;定期物理/逻辑备份与恢复演练。
- 维护窗口
- 分片集群的 balancer 会在后台迁移 chunk,建议在低峰期调整分片策略或迁移分片;变更前后使用 sh.status() 与监控确认均衡效果。