第一次使用MongoDB来存储数据,没有看mongo的官方文档,所以踩了不少坑,今天终于得空总结了下mongo新手容易犯的错。
不用多说mongodb肯定是部署在Linux系统上性能最佳,但是linux系统的一些默认配置却不是mongo建议的。我用的linux操作系统是centos6.5,最近遇到了一个问题是mongodb的索引已经有19g左右但是用mongostat查看mongodb的物理内存使用一直在10g左右徘徊。一开始以为是其他软件占用导致mongo申请不到内存,后面清理完之后mongo的内存依然无法上来,导致有些大集合的查询非常慢尽管查询有走索引。
后面突然想到mongodb启动的时候好像有很多warning,于是去认真看了下发现下面这个问题:
去度娘了下才知道原来linux有根据cpu内核数量来将内存分配给node的大小进行了限制,这个默认的内存分配策略叫numa。至于NUMA的含义,简单点说,在有多个物理CPU的架构下,NUMA把内存分为本地和远程,每个物理CPU都有属于自己的本地内存,访问本地内存速度快于访问远程内存,缺省情况下,每个物理CPU只能访问属于自己的本地内存。对于MongoDB这种需要大内存的服务来说就可能造成内存不足,NUMA的详细介绍,可以参考老外的文章。
理论上,MySQL、Redis、Memcached等等都可能会受到NUMA的影响,需要留意。
解决方法:
1.在原启动命令前面加numactl –interleave=all
如# numactl –interleave=all ${MONGODB_HOME}/bin/mongod –config conf/mongodb.conf
2.修改内核参数
echo 0 > /proc/sys/vm/zone_reclaim_mode
还有一个是hugepage_transport的问题,需要禁用该项。
解决方法:
1.创建文件/etc/init.d/disable-transparent-hugepages,内容如下:
#!/bin/sh
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if [ -d /sys/kernel/mm/transparent_hugepage ]; then
thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
return 0
fi
echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag
unset thp_path
;;
esac
2.make it executable
#sudo chmod 755 /etc/init.d/disable-transparent-hugepages
3.Configure your operating system to run it on boot
#sudo chkconfig --add disable-transparent-hugepages
重启即可,重点在下面这段使其启动时执行
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi