Skip to content

MongoDB 性能优化

硬件

  • SSD
  • RAID10
  • 万兆网卡

系统参数

ext4/xfs

关闭NUMA

mongodb相关命令前加上numactl--interleave=all,以关闭NUMA功能

numactl --interleave=all /opt/mongodb/bin/mongod -f /opt/mongodb/conf/mongo.conf

关闭磁盘预读

为了进一步减少真实的I/O操作次数,磁盘每次都会进行预读,即读取数据的同时按顺序向后读取一定长度的数据并置入内存。磁盘预读的前提是大部分数据是连续读取的,例如对视频文件读取一部分之后,一定会读取后面的数据段。然而在大多数场景中,MongoDB会随机访问磁盘,因此,预读对性能的提升帮助有限,反而会产生一些无效的内存占用。

## 查看
blockdev --report
## 修改
blockdev --setra 0 /dev/sda

关闭透明大页

由于数据库对内存的访问一般都是随机访问,而不是连续访问。透明大页(Transparent Huge Pages, THP)在随机访问模式上反而制约了MongoDB的性能。

echo never > /sys/kernel/mm/transparent_hugepage/enable

关闭atime选项

文件系统默认会记录每个文件的访问时间,由于MongoDB可能会频繁访问数据文件,将访问时间记录禁用可以获得一些性能提升。在Linux系统中挂载数据分区时使用noatime选项。

echo "/dev/sdb /data xfs noatime,nodiratime 0 0" >> /etc/fstab

修改资源限制

MongoDB会视情况动态创建连接,在默认的网络I/O模型中,每个连接会使用一个线程,同时包含一个文件描述符句柄。

编辑/etc/sysctl.conf文件

fs.file-max = 98000
kernel.pid_max = 64000
kernel.threads-max = 64000

保存设置

sysctl -p

ulimit -v unlimited
ulimit -m unlimited
ulimit -n 64000

数据库配置

启用Journal日志

MongoDB采用了缓冲延迟刷盘的机制,写入数据存在最高60s丢失的风险。Journal日志功能提供断电保护,可将损失风险降低到100ms以内。

日志和数据分离

建议将MongoDB运行日志、Journal预写日志、数据文件存放到不同的磁盘,有利于提升整体I/O的吞吐量。

保持时钟同步

建议使用NTP服务来保持节点间的时钟同步,最好延迟不要超过1s。MongoDB对时钟偏移做了一些兼容,但分布式节点之间的时钟延迟仍然可能产生一些未知的影响。

连接数限制

  • 每个连接需要占用一个文件句柄,同时还包括TCP协议栈的独立读写缓冲区。
  • 默认情况下,MongoDB为每个连接分配一个线程,默认的线程栈最大为1MB的空间。

在MongoDB服务器端,通过配置 net.maxIncomingConnections 来限制最高的并发连接数,这个值建议不大于1万。

在客户端方面,驱动默认为每个远程主机连接设置100的连接数上限,应用可适当进行调整。

Reference

  • 《MongoDB进阶与实战:微服务整合、性能优化、架构管理》(唐卓章)

Disclaimer
  1. License under CC BY-NC 4.0
  2. Copyright issue feedback me#imzye.me, replace # with @
  3. Not all the commands and scripts are tested in production environment, use at your own risk
  4. No privacy information is collected here
Try my iOS App