CentOS 环境下 MongoDB 性能调优要点
一 硬件与操作系统层优化
- 使用 SSD/NVMe 降低 I/O 延迟,优先选择更高 IOPS 的磁盘与阵列;为数据盘挂载时建议开启 noatime,减少元数据写入。
- 合理规划内存:让 WiredTiger 缓存有足够空间容纳热点数据与索引;在自托管环境通常将缓存设置为物理内存的50%–75%(需为系统与其他进程预留)。
- 关闭 Transparent Huge Pages(THP),减少内存管理抖动;可通过 tuned 或 systemd 服务在开机时禁用。
- 调整内核与资源限制:提高 文件描述符/进程数(如 ulimit -n/-u 到较高值),优化 磁盘调度算法(SSD 常用 none/noop),并适度降低 vm.swappiness 以减少换页。
- 连接与内存:控制总连接数,避免每个客户端维持大量长连接;必要时通过连接池限制与合理的应用重试/超时策略降低连接风暴。
二 存储引擎与关键参数
- 使用 WiredTiger 作为默认存储引擎,启用压缩(如 snappy/zlib)以节省空间、适度增加 CPU 使用;在写入密集场景可适当提高 journal.commitIntervalMs(如 100 ms)以合并日志提交,但需权衡持久性与恢复点目标。
- 配置 storage.wiredTiger.engineConfig.cacheSizeGB:自托管环境建议为内存的50%–75%;在部分云托管环境中,WiredTiger 缓存可能被限定为实例内存的60%,需结合实例规格与负载评估。
- 监控 WiredTiger 缓存健康度:当缓存使用接近上限(如 >95%)或 脏数据占比持续超过 20% 时,优先考虑降低单位时间写入速率、扩容内存或提升清理脏数据线程数(如将 eviction 线程调至 threads_max=8, threads_min=4)。
- 连接内存与回收:MongoDB 使用 tcmalloc 管理内存,若观察到应用占用内存高但操作系统层面未回收,可适当提高 tcmallocReleaseRate(如 5.0)以加速归还;同时控制并发连接数,避免线程栈与临时缓冲占用过多内存。
三 索引与查询优化
- 为高频查询路径建立合适的索引:优先使用 单键索引、复合索引(最多 32 个键),必要时使用 文本索引 与 地理空间索引;复合索引需遵循最左前缀原则与排序/范围键顺序。
- 使用 覆盖索引 减少回表;对大结果集使用 投影 仅返回必要字段;分页建议基于 _id 或基于索引的范围条件,避免深分页带来的性能退化。
- 借助 explain(“executionStats”) 与慢日志定位问题:重点关注 DocsExamined 与 KeysExamined,当 DocsExamined 很大时考虑新增/调整索引;当 KeysExamined 大而返回行数很小时,优化索引或改写查询。
- 字符串比较需与索引 Collation 一致;若查询未指定相同排序规则,可能无法命中索引。
- 谨慎使用 $or,其可能导致索引失效;尽量改写为 $in 或复合索引可覆盖的形式。
四 副本集 分片与读写分离
- 读多写少场景可开启 读偏好从节点(secondaryPreferred),降低主节点压力;确保关键业务读一致性要求下使用 readConcern 合理权衡一致性与延迟。
- 大数据量或高并发写入场景引入 分片,合理选择 分片键 避免数据倾斜与热点;分片前先完成索引设计与容量评估。
- 合理设置 oplog 大小(常见为磁盘空间的约 5%,需结合变更窗口与恢复目标调整),确保副本集具备足够的变更保留能力。
五 监控 维护与变更流程
- 持续监控:使用 mongostat、mongotop 观察插入/查询/更新/删除速率与磁盘/网络活动;通过 db.serverStatus() 获取内存、连接、缓存等细项;结合 慢查询日志 与 explain 定位瓶颈。
- 日志与维护:启用 日志轮转 防止日志无限增长;对高更新集合按需执行 compact 或重建索引以回收碎片;定期清理无用数据,避免集合与索引膨胀。
- 变更流程:任何参数或索引调整先在 测试环境 验证,评估对延迟、吞吐与资源占用的影响,再灰度/滚动发布,确保可回滚与可观测。