Linux MongoDB性能调优技巧
小樊
38
2025-11-26 20:15:37
Linux 上 MongoDB 性能调优要点
一 系统层面优化
- 文件描述符与进程数:将 open files 与 nproc 提升到高位(如 1048576/524288),持久化到 /etc/security/limits.conf,避免 “too many open files/connections”。
- 线程栈与连接内存:适度降低 ulimit -s(如 1024 KB)以减少每个连接栈占用;连接越多,内存与上下文切换开销越大。
- 透明大页 THP:MongoDB 随机小 I/O 较多,建议关闭 Transparent Huge Pages(/sys/kernel/mm/transparent_hugepage/{enabled,defrag} 设为 never)。
- 文件系统与挂载:WiredTiger 推荐 XFS,并挂载 noatime,nodiratime 减少元数据写入。
- 预读 readahead:随机访问场景建议将设备预读调小(如 blockdev --setra 32 /dev/sdX)。
- NUMA:NUMA 架构下建议禁用或绑定 NUMA,避免跨节点访问带来的性能劣化。
- 时间同步:副本集/分片依赖时钟一致性,部署 NTP 保证节点间时间误差在可接受范围。
二 存储引擎与缓存调优
- WiredTiger 缓存大小:将 storage.wiredTiger.engineConfig.cacheSizeGB 设为能容纳业务“工作集”的大小,通常约为内存的 40%–60%;容器/共享环境需手动限制,避免 OOM。
- 监控与阈值:通过 db.serverStatus().wiredTiger.cache 观察,若 cache used ≥ 95% 或 dirty ≥ 20% 会触发更激进的淘汰,用户线程可能参与,表现为延迟上升;必要时提升内存规格或调大后台淘汰线程。
- 后台淘汰线程:副本集 4.0+ 可调 wiredTigerEngineRuntimeConfig: eviction=(threads_max=8,threads_min=4)(默认 4/1)。
- 压缩策略:集合数据压缩 storage.wiredTiger.collectionConfig.blockCompressor 常用 snappy/zstd(写密集优先 snappy,读密集/存储紧张优先 zstd);网络压缩 net.compression.compressors 建议包含 zstd/snappy,在云环境/跨机房收益明显。
- 目录隔离:开启 storage.directoryPerDB 与 storage.wiredTiger.engineConfig.directoryForIndexes,将多库/索引与数据分离,缓解 I/O 争用(单盘收益有限)。
三 索引与查询优化
- 索引类型选择:按场景使用 单键、复合、文本、地理空间、哈希 索引;等值/范围/排序优先 B-Tree。
- 复合索引设计:遵循 ESR 规则(Equality, Sort, Range);等值字段放左,范围/排序靠右;避免重复/包含关系导致的冗余索引。
- 覆盖查询:让返回字段全部落在索引中,并用 explain(“executionStats”) 验证 totalDocsExamined=0;分片集群需把 分片键 纳入索引。
- 排序与内存:避免大数据集内存排序,尽量用索引排序;必要时增加合适索引或改写查询。
- 执行计划与慢日志:关注 COLLSCAN、IXSCAN、DocsExamined、KeysExamined;用 explain 与慢日志定位缺失/低效索引并优化。
- 字符串比较与排序规则:查询与索引的 collation 需一致,否则无法使用该索引做字符串比较。
四 连接与内存回收
- 连接与内存:每个连接对应请求线程,线程栈通常最多 1 MB;大量连接会放大内存与调度开销。
- 连接数建议:驱动默认连接池约 100;多客户端场景建议将全库长连接总量控制在 ≤1000,并合理设置客户端连接池大小。
- tcmalloc 回收:若内存使用率长期偏高,可开启 tcmallocAggressiveMemoryDecommit=1 并渐进调大 tcmallocReleaseRate(1→3→5) 以加速归还内存至操作系统(低峰期调整)。
- 观察指标:用 db.serverStatus().tcmalloc 查看 Bytes in use by application 与 Bytes in page heap freelist,判断应用占用与未归还内存。
五 监控与容量规划
- 工具与指标:用 mongostat、mongotop 观察吞吐、锁、I/O 与热点集合;结合 db.serverStatus() 深入分析引擎缓存、tcmalloc、连接与执行统计。
- 存储与 I/O:优先 SSD;多库/多业务共享实例时,结合 directoryPerDB/index 分离 与多磁盘/卷做 I/O 隔离;合理设置 readahead 与文件系统挂载参数。
- 扩展策略:读压力大可用 副本集读从 分担;数据/写入规模大时引入 分片 横向扩展。
- 变更流程:任何参数调整先在测试环境验证,遵循“小步变更—回滚预案—低峰期执行—持续监控”的闭环。