mongos节点必须高可用:它是无状态但单点入口的路由节点,所有请求必经,挂掉则集群“断网”;需部署3–5个实例并启用客户端粘性连接或DNS轮询,避免元数据不一致与路由失败。

为什么不能只用一个mongos
单个 mongos 是单点故障源,且连接数、查询路由压力会随应用并发增长而迅速成为瓶颈。官方明确建议:生产环境必须部署多个 mongos 实例,并配合客户端关联性(sticky connection)或负载均衡策略,否则高并发下会出现连接拒绝、路由超时或元数据同步延迟。
启动多个mongos的实操要点
每个 mongos 都是无状态进程,不存数据,但必须能稳定访问配置服务器副本集(cfgset)。关键不是“多开几个进程”,而是确保它们能一致、低延迟地读取集群元数据。
-
mongos启动时必须通过--configdb指向配置服务器副本集名称和成员列表,例如:mongos --configdb cfgset/cfg1.example.net:40002,cfg2.example.net:40002,cfg3.example.net:40002 --port 20000 - 所有
mongos实例必须使用**完全相同的配置服务器连接字符串**,否则可能因元数据视图不一致导致路由错误 - 不要为不同
mongos分配相同端口;建议统一规划端口段(如 20000–20003),并在应用连接串中轮询或通过 DNS SRV 记录分发 - 日志路径、PID 文件需各自独立,避免文件冲突;
mongos不需要dbpath,但必须指定--logpath
客户端怎么连多个mongos才不翻车
直接把多个 mongos 地址塞进连接串(如 mongodb://mongos1:20000,mongos2:20000/?replicaSet=xxx)是错的——mongos 不是副本集成员,不支持 replicaSet 参数。客户端 SDK 会把它当普通 mongod 处理,导致路由失效或认证失败。
- 正确做法是:用 DNS 负载均衡(如 round-robin A 记录)或四层 LB(如 HAProxy、Nginx Stream)前置,后端真实指向多个
mongos实例 - LB 必须开启 **client affinity(粘性会话)**,否则同一个逻辑连接可能被轮到不同
mongos,触发重复 auth 或事务上下文丢失 - Java Driver 等支持
mongos发现机制,但前提是连接串里只写一个地址(如mongodb://mongos-primary:20000),再靠服务发现+心跳自动感知其他mongos—— 这依赖mongos间元数据同步及时,不推荐用于强一致性场景
容易被忽略的性能陷阱
mongos 数量不是越多越好。它每秒会向配置服务器发起心跳和元数据拉取,节点越多,对配置服务器副本集的读压力越大。实测中,超过 8 个 mongos 后,config 副本集 CPU 和网络延迟明显上升,反而拖慢整体路由响应。
- 推荐数量:3–5 个,足够覆盖大多数中大型业务的可用性与吞吐需求
- 如果已有
mongod节点空闲资源,可将mongos与分片或配置服务器共部署(注意端口隔离),减少跨机网络跳数 - 务必监控
mongos的shardingStatistics命令输出,重点关注hostInfo.configServerHosts是否全部可达,以及version字段是否在各实例间保持一致
配置服务器副本集的稳定性,才是多个 mongos 能否协同工作的底层前提。别只盯着加 mongos 数量,先确保 cfgset 的选举正常、心跳延迟低于 50ms。











