Linux 上实现 MongoDB 负载均衡的推荐方案
- 使用 副本集 Replica Set 实现高可用与读扩展:写操作集中在 Primary,读请求可按需分发到 Secondary,并在主故障时自动切换,适合大多数在线业务。
- 使用 分片 Sharding 实现水平扩展:将数据按 shard key 分布到多个分片,每个分片通常是一个副本集,适合数据量大、并发高的场景。
- 如需在连接层做统一入口与连接复用,可在前端部署 HAProxy/Nginx(TCP 转发) 或云厂商 LB,但应用优先使用副本集 URI 直连集群以获得自动故障切换与读写偏好能力。
方案一 副本集 Replica Set 实现读写分离与高可用
- 准备与安装
- 至少 3 个节点(优先全数据节点,尽量避免仅投票的 Arbiter),安装同版本 MongoDB,开启 NTP 时间同步,放行 27017/TCP 防火墙。
- 配置每个节点的 /etc/mongod.conf(示例)
- storage.dbPath、systemLog、net.port、net.bindIp 按实际环境设置
- replication.replSetName 保持一致(如:rs0)
- 启动与初始化
- systemctl start mongod(或 mongod -f /etc/mongod.conf)
- 连接任一节点执行:
- rs.initiate({ _id: “rs0”, members: [{ _id:0, host:“10.0.0.1:27017” }, { _id:1, host:“10.0.0.2:27017” }, { _id:2, host:“10.0.0.3:27017” }] })
- rs.status() 检查角色与健康
- 连接与应用要点
- 生产连接使用副本集 URI:
- mongodb://10.0.0.1:27017,10.0.0.2:27017,10.0.0.3:27017/db?replicaSet=rs0
- 读偏好示例:readPreference=secondaryPreferred(报表/统计可走从节点;强一致业务走主节点)
- 从节点默认不可读,需设置读偏好或在会话中执行 rs.slaveOk()(旧驱动)/ secondaryOk(新驱动语义)
- 适用场景
- 读写分离、读多写少、需要自动故障切换与高可用的在线业务。
方案二 分片 Sharding 实现水平扩展
- 集群组件与端口规划
- Config Servers(配置服务器):建议 3 个 副本集,端口 27019
- Shard Servers(分片):每个分片为副本集,端口 27018
- mongos(路由):入口进程,端口 27017
- 启动与配置步骤
- 启动配置服务器(示例)
- mongod --configsvr --replSet cfgrs --dbpath /data/config --port 27019
- 启动分片(示例)
- mongod --shardsvr --replSet shardrs0 --dbpath /data/shard0 --port 27018
- 启动 mongos(示例)
- mongos --configdb cfgrs/10.0.0.11:27019,10.0.0.12:27019,10.0.0.13:27019 --port 27017
- 连接到 mongos(如 10.0.0.10:27017),添加分片:
- sh.addShard(“shardrs0/10.0.0.21:27018,10.0.0.22:27018,10.0.0.23:27018”)
- 对目标库/集合启用分片并指定 shard key:
- sh.enableSharding(“mydb”)
- sh.shardCollection(“mydb.mycoll”, { “shardKey”: 1 })
- 关键注意
- 必须先启用数据库/集合分片,数据才会按 shard key 分布到各分片;shard key 选择直接影响负载均衡与查询性能。
方案三 在连接层使用 HAProxy 或 Nginx 做负载均衡(可选)
- 适用场景
- 需要统一入口、连接复用、与现有四层/七层 LB 体系打通;或在无法使用副本集 URI 的旧客户端场景。
- HAProxy 示例(/etc/haproxy/haproxy.cfg,TCP 转发)
- frontend mongo_frontend
- bind *:27017
- default_backend mongo_backend
- backend mongo_backend
- mode tcp
- balance roundrobin
- server mongo1 10.0.0.1:27017 check
- server mongo2 10.0.0.2:27017 check
- server mongo3 10.0.0.3:27017 check
- 启动:systemctl start haproxy
- 验证
- mongo --host <haproxy_ip> --port 27017 执行读写,观察连接分发与健康检查。
- 重要提示
- 使用 LB 时,建议开启 TCP 健康检查 与 应用重连/重试;MongoDB 驱动直连副本集可获得更细粒度的读写偏好与故障切换控制。
生产要点与常见问题
- 连接与故障切换
- 应用应使用 副本集 URI;主从切换期间写会短暂失败/阻塞,需设置 writeConcern 与重试机制。
- 读写分离与一致性
- 从节点可能有复制延迟;强一致业务走主节点,报表/统计可用 secondaryPreferred。
- 批量与 oplog
- 大批量 delete/update 会占用 oplog,可能导致从节点延迟或掉队;建议分批执行并监控 oplog 大小。
- 监控与告警
- 关注主从角色变化、复制延迟、磁盘使用率、连接数与慢查询,结合 Ops Manager/Prometheus 建立告警。