需在os层查cpu和内存:用top -b -n1 | head -20或psutil脚本;主节点负载高常因读请求未分流至从节点,须检查readpreference配置、slavedelay、hidden属性及客户端路由缓存。

怎么查 MongoDB 集群里每个节点的 CPU 和内存实际占用
直接看 mongostat 不行——它只反映 MongoDB 进程内部指标(如 opcount、queue),不暴露宿主机硬件负载。真实压力不均衡,得跳出 mongod 进程看 OS 层。
在每个节点上执行:
top -b -n1 | head -20或更精准用
psutil 脚本采集(Python 示例):import psutil; print(f"CPU: {psutil.cpu_percent(interval=1)}%, MEM: {psutil.virtual_memory().percent}%")
- 别依赖
db.serverStatus()里的extra_info字段——它只在 Windows 上有 CPU 使用率,Linux 下为空 -
mongostat的netIn/netOut高,可能掩盖了磁盘 I/O 瓶颈,需同步查iostat -x 1 3 - 副本集主节点若 CPU 持续高于从节点 20%+,优先检查是否有未绑定
readPreference=secondary的读请求打到了主库
为什么 rs.status() 显示正常但主节点负载远高于从节点
副本集状态正常 ≠ 流量分发合理。MongoDB 默认所有读写都走主节点,除非客户端显式指定读偏好或驱动配置了 readPreference。
- Java 驱动里没设
ReadPreference.secondary(),Node.js 里漏掉readPreference: 'secondary'选项,都会让读请求全压主库 - 从节点启用了
slaveDelay或hidden: true,会导致它无法被选为读节点,但rs.status()仍显示stateStr: "SECONDARY" - 网络分区后自动恢复时,旧主节点可能短暂降级又升主,但连接池里的客户端还缓存着旧路由信息,造成“逻辑主备”和“物理主备”错位
用 mongotop 和 mongostat 定位具体集合/操作的倾斜点
mongotop 按集合维度统计读写毫秒级耗时,mongostat 按秒级看整体 ops 分布——两者结合才能判断是「某集合读多」还是「某类操作(如 updateMany)集中爆发」。
- 运行
mongotop --host <primary_host>:27017 --ssl</primary_host>,重点关注total列持续高于其他节点同集合值的项 -
mongostat中若qr(read queue)在主节点长期 >5,但从节点qr≈ 0,说明读请求根本没分流过去 - 注意:开启
mongotop会轻微影响性能,生产环境建议采样 10 秒而非持续运行 -
mongostat默认不显示数据库名,加-o参数可输出字段名,避免误读列顺序
监控脚本里容易忽略的部署差异点
集群节点往往跨不同物理机、容器或云厂商实例,硬件规格、内核参数、cgroup 限制可能不一致——同一套监控脚本跑出来,数值不可直接横向比较。
- Docker 部署的节点,
psutil.cpu_count()返回的是容器可见核数,不是宿主机总核数,需改用os.sched_getaffinity(0)获取实际绑核 - 阿里云 ECS 实例启用突发性能实例(T5/T6)时,CPU 积分耗尽会导致
top显示 100% 却无高负载进程,需查/proc/sys/kernel/cpu_burst或云监控中的 “CPU 积分余额” - 从节点挂载了低速 NAS 存储,
iostat的%util接近 100%,但await高而svctm低,说明是存储延迟问题,不是 MongoDB 本身压力大
硬件利用率差异背后,往往是配置漂移、客户端行为未收敛、或者基础设施层的隐形约束。盯着 rs.status() 看不出问题,得一层层剥开看进程、OS、硬件的真实反馈。










