- A+
mongodb是一个nosql非关系型数据库,是大数据方面用的比较多的非关系型数据库,提供高并发,其在设计的时候将磁盘上的数据与内存做映射关系,那么需要读取磁盘的时候,可以直接读取内存,提高速度,这是其优点。
另外一方面,mongodb不对内存进行直接管理而是利用操作系统本身的内存关系机制进行管理,因此不能直接在mongodb本上的配置中指定最大内存占用,而如果不做限制,默认mongodb会将系统中95%左右的内存都占用掉(根据这段时间线上系统运行状态发现),导致系统可用内存较少,在这种情况下,mongodb可能会莫名其妙的挂掉(日志中没有记录挂掉原因,直接就没有后续日志记录),个人认为可能是系统可用内存较少时,当遇到其他需要消耗内存的情况,系统为了释放资源把mongodb枪毙了,不过这个是自己的猜测没有证据。
为了控制mongodb这个内存吞噬小怪兽,尝试过网上说的一些方法,其中最多是使用ulimit命令来限制mongodb的使用,但是尝试后效果不好。
网上说有2种限制的参数,
一: 是使用ulimit -m XXX 限制物理内存使用,在给mongodb的进程mongod配置属于mongod用户、mongod组后,专门设置针对mongod用户ulimt -m 2097152 (单位为Kbytes,2097152=2048*1024=2G),限制mongod用户物理内存使用为2G,测试发现,这个限制没有起作用,操作2G物理内存后还是会增长。
二: 是使用ulimit -v XXX 限制虚拟内存使用,这个设置方法跟上面一样,设置ulimit -v 2097152 ,这个倒是会限制住mongod用户的内存使用为2G以下,但是mongod进程在使用虚拟内存达到2G后,如果还对mongodb进行数据插入等操作,那么由于mongod进程无法再获取内存,直接就挂掉。
看来使用ulimit来限制mongodb的方法行不通,至少我这里没试验成功。
后来网上找了下,发现cgroup这个东西可以限制内存使用,于是就去找了相关资料,并自己配置试验了下,发现可以,现在线上系统用这个跑了快一周了,暂时没发现什么问题,内存被限制住了。
cgroup是linux内核的一个功能,用于管理系统各种资源,包括cpu、内存等其他资源,个人只看了下内存的使用。可以直接使用cgroup的相关命令配置,也可以使用预先配置cgconfig服务的相关配置文件来管理。
1. 服务器环境
[root@sinohytec ~]# cat /etc/redhat-release CentOS release 6.5 (Final) [root@sinohytec ~]# hostname sinohytec [root@sinohytec ~]# hostname -I 218.240.21.134
2. 安装
yum -y install libcgroup
3. 配置
3.1 配置cgconfig配置文件
[root@sinohytec ~]# cat /etc/cgconfig.conf mount { cpuset = /cgroup/cpuset; cpu = /cgroup/cpu; cpuacct = /cgroup/cpuacct; memory = /cgroup/memory; devices = /cgroup/devices; freezer = /cgroup/freezer; net_cls = /cgroup/net_cls; blkio = /cgroup/blkio; } group DBLimitedGroup { memory { memory.limit_in_bytes = "1073741824"; } }
说明:
上面配置文件中,mount{...} 这一部分是安装libcgroup后生成的/etc/cgconfig.conf中默认有的,目的是定义各个子系统的挂载点,可以不用管。
为了限制mongodb,这里定义了一个group名字叫做DBLimitedGroup,这个group中定义了对内存memory进行限制,限制的项为memory.limit_in_bytes ,它的值为1073741824(1073741824/1024/1024/1024=1GB),线上服务器是16G的内存,这里设置限制为1G给mongodb。根据自己的情况设置,数值的单位为 byte字节,比如1G=1*1024*1024*1024=1073741824(byte)
-3.2 然后配置cgrules.conf
[root@sinohytec ~]# cat/etc/cgrules.conf # /etc/cgrules.conf #The format of this file is described in cgrules.conf(5) #manual page. # # Example: #<user><controllers><destination> #@studentcpu,memory usergroup/student/ #peter cpu test1/ #% memory test2/ # End of file *:mongod memory DBLimitedGroup/
这个cgrules.conf是配置cgexec命令的默认配置,后面会用到cgexec来执行mongod的程序,"#"开头是注释,不用管,配置查看最后一行。
上面的意思为:
*: 所有的用户以及用户组
mongod: mongod程序名(进程)
memory: 使用memory子系统中的配置
DBLimitedGroup: cgroup.conf中自定义的group
全部连在一起就是说,执行cgexec时,如果满足“任何用户任何组执行mongod程序,那么被执行的进程(及mongod进程)将满足memory内存子系统中的DBLimitedGroup中的所有限制”
而DBLimitedGroup中的限制就是,限制内存使用为32G。
这样使用cgroup就限制了指定进程(这里是mongod进程)的(物理)内存使用。
4. 启动服务并加入开机自启动
service cgconfig status chkconfig cgconfig on chkconfig --list cgconfig
5. 重启mongodb服务
注:启动mongodb服务后即可观察mongodb消耗内存情况
参考文献:http://xiaotong.blog.51cto.com/4312502/1783768