为什么单机撑不住
单机 MongoDB 的问题很直白:机器挂了数据就没了,宕机期间业务完全中断;机器性能到头了,读写都卡在硬件上限。要解决这两个问题,方向也直白:多副本保证可用性,分片扩展容量。MongoDB 把这两个能力内建为副本集与分片集群,副本集解决"挂了怎么办",分片解决"装不下、跑不动怎么办"。
理解这两个机制,是 MongoDB 运维与架构设计的分水岭。本文从副本集讲起,再讲分片集群的搭建与扩容,最后给出一份可直接落地的运维清单。
- 副本集主从复制加自动故障转移。
- 心跳节点间选举与健康探测。
- 分片按分片键把数据分布到多组。
- 均衡数据在各分片间自动迁移。
副本集:主从与自动故障转移
副本集是一个由若干节点组成的高可用组:一个主节点负责读写,其余是从节点同步数据。主节点宕机后,剩余节点通过心跳投票选出新的主节点,通常几秒内完成,业务几乎无感知。标准部署是三节点:一主一从一仲裁,仲裁节点不存数据、只参与投票,成本最低。
// 初始化副本集
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo-1:27017" },
{ _id: 1, host: "mongo-2:27017" },
{ _id: 2, host: "mongo-3:27017", arbiterOnly: true },
],
});
副本集还有一个常被忽略的用途:滚动维护。升级版本、调整配置都可以逐个摘节点操作,主节点切换后继续处理下一个,全程不中断服务。
读写分离与一致性
副本集默认读写都走主节点,从节点只做备份。读压力大时,可以把读分散到从节点:连接串里指定 readPreference=secondary。但要注意,从节点数据有复制延迟,刚写入就读从库可能读到旧数据。一致性要求高的读仍走主节点,能容忍延迟的报表、统计类查询走从节点。
// 连接串:读偏向从节点
mongodb://mongo-1,mongo-2,mongo-3/?replicaSet=rs0&readPreference=secondaryPreferred
- primary默认,强一致,全走主。
- secondary只读从,接受延迟。
- nearest就近读,跨机房友好。
写安全级别也要按业务定:w=1 主节点确认即可,吞吐高;w=majority 多数派确认,数据更稳,主节点挂掉也不丢已确认写入。对账、支付类关键写,用 majority。
分片集群与分片键
副本集解决可用性,容量与性能天花板要靠分片。分片集群由三部分组成:mongos 路由层接收请求,config server 保存元数据,若干个分片(每个分片本身是一个副本集)存数据。写入时按分片键路由到对应分片,数据天然分布到多组机器。
分片键的选择是成败关键:要有足够基数,避免大量数据落在同一个值上;要分布均匀,写入热点不能集中;查询要能带分片键,否则路由层全片扫描。常见好键:用户 ID 哈希、订单号、时间加随机后缀。
// 开启分片并建索引
sh.enableSharding("appdb")
sh.shardCollection("appdb.orders", { orderId: "hashed" })
分片键一旦定下来很难改,设计阶段就要想清楚业务形态。用哈希分片键可以强制打散热点,但范围查询会退化成全分片扫描,两者按查询模式权衡。
扩容与数据均衡
分片集群的扩容是平滑的:新加一个分片组,MongoDB 的均衡器会自动把数据 chunk 从高分片迁往新分片,迁移期间不影响读写。缩容则反着来,先把数据均衡走再下线分片。均衡器有默认节奏,避免与业务高峰冲突,迁移本身也消耗带宽与 IO,必要时限制迁移窗口。
// 查看集群分片状态
sh.status()
扩容前要做容量评估:当前数据量与增长速率决定新分片数量;单分片内存与磁盘规格决定能扛的 chunk 数。分片太碎(chunk 过多)会放大元数据开销,适当调大 chunk 大小可以减少迁移压力。
运维要点与监控
副本集与分片集群的运维重点:备份与恢复要覆盖到 config server 与分片元数据,只备数据不备元数据,恢复时会找不回路由关系;监控要看主从延迟、心跳状态、chunk 分布与磁盘水位;节点硬件故障要按流程摘除、替换,避免脑裂(两个主节点同时对外)——脑裂由多数派选举机制避免,投票节点必须过半数在线。
// 查看复制状态与延迟
rs.status()
- 延迟主从复制延迟秒级以下。
- 心跳节点健康,主节点唯一。
- 均衡分片间数据分布偏差。
- 磁盘水位超线预警扩容。
跨机房部署时,把投票节点放独立机房,避免机房故障带走全部仲裁。连接串里配置多个 mongos 入口,mongos 本身也要做负载均衡与高可用。
落地清单
- 生产环境至少三节点副本集,避免单点。
- 读偏好按一致性需求选 primary 或 secondary。
- 关键写用 w=majority,兼顾安全与吞吐。
- 数据量或性能到顶时启用分片,选好分片键。
- 扩容走均衡器平滑迁移,避开业务高峰。
- 备份覆盖元数据,监控延迟、心跳与磁盘水位。