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
- License under
CC BY-NC 4.0
- Copyright issue feedback
me#imzye.me
, replace # with @ - Not all the commands and scripts are tested in production environment, use at your own risk
- No privacy information is collected here