MongoDB默认采用WiredTiger存储引擎(自3.0版本起成为默认),其内置的LRU(最近最少使用)缓存是内存管理的核心。缓存用于存储热点数据(文档)和索引,减少磁盘I/O次数,直接影响数据库读性能。
关键配置:通过storage.wiredTiger.engineConfig.cacheSizeGB
参数设置缓存大小,建议值为系统可用内存的40%-60%(需预留部分内存给操作系统及其他进程,如系统日志、SSH等)。例如,16GB内存的服务器可配置为cacheSizeGB: 6-8
。
实践建议:
db.serverStatus().wiredTiger.cache
命令监控缓存使用情况,重点关注bytes currently in the cache
(当前缓存占用量)和pages read into cache
(从磁盘加载的页数):若bytes currently in the cache
长期接近maximum bytes configured
(缓存最大容量),或pages read into cache
持续增长,说明缓存不足,需扩容。vm.overcommit_memory
参数决定内核是否允许内存超额分配(即申请的内存超过物理内存+交换空间)。设置为1
(允许超额分配)可避免MongoDB因内存分配失败而崩溃,但需注意:若应用程序(如MongoDB)过度申请内存,可能导致系统内存耗尽。
配置方法:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory # 临时生效 echo "vm.overcommit_memory = 1" | sudo tee -a /etc/sysctl.conf # 永久生效
vm.swappiness
参数控制内核使用交换空间(Swap)的倾向,取值范围为0-100(0表示尽量避免使用Swap,100表示积极使用)。MongoDB是内存密集型应用,建议设置为10或更低,减少Swap使用以提升性能(Swap会显著增加磁盘I/O延迟)。
配置方法:
echo 10 | sudo tee /proc/sys/vm/swappiness # 临时生效 echo "vm.swappiness = 10" | sudo tee -a /etc/sysctl.conf # 永久生效
透明大页(Transparent Huge Pages, THP)会合并小内存页为大页,减少内存管理开销,但对MongoDB而言,THP可能导致内存碎片化,增加延迟。建议关闭THP:
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
(需将上述命令添加到系统启动脚本中,确保永久生效)
索引是提升查询性能的关键,但也会占用内存(索引数据需缓存在WiredTiger缓存中)。优化索引可减少内存占用,提升查询效率:
user_id
、order_date
)创建索引,避免全表扫描;db.collection.find({status: "active"}, {name: 1})
),可使用覆盖索引,避免读取文档数据,减少内存占用;db.collection.explain("executionStats").find({query})
命令查看索引使用情况,删除未使用或低效的索引。定期监控内存使用情况是优化的前提,MongoDB提供多种工具查看内存状态:
db.serverStatus().mem
命令:查看内存使用概况,包括resident(常驻内存,即实际使用的物理内存)、virtual(虚拟内存)、mapped(映射到内存的数据大小)等指标;db.serverStatus().wiredTiger.cache
命令:查看WiredTiger缓存的详细统计信息(如缓存命中率、从磁盘加载的页数);mongostat
(监控每秒内存使用变化)、mongotop
(监控集合级内存使用)、Prometheus+Granafa
(可视化监控)。调优方向:
resident
内存长期接近系统物理内存,且pages read into cache
持续增长,说明内存不足,需扩容服务器或优化缓存配置;wiredTiger.cache.bytes dirty
(脏页,即未写入磁盘的数据)过高,可能引发性能问题,需调整storage.wiredTiger.engineConfig.flusherConfig
参数(如增加flushInterval
,减少刷盘频率)。storage.wiredTiger.collectionConfig.blockCompressor
参数设置数据压缩算法(可选none
、snappy
、zlib
、zstd
),减少内存占用和磁盘I/O。默认使用snappy
(兼顾压缩率和CPU开销),写密集场景建议用snappy
,读密集场景建议用zstd
(压缩率高);directoryForIndexes
参数将索引文件与集合数据文件分离(如将collection
目录挂载到/data/db/collection
,index
目录挂载到/data/db/index
),分散磁盘I/O压力,减少内存争用;bulkWrite
),减少内存波动。