(转载)MongoDB与内存ITeye - 娱乐之横扫全球

(转载)MongoDB与内存ITeye

2019-01-11 11:00:27 | 作者: 思萱 | 标签: 内存,可以,运用 | 浏览: 2922

凡是初度触摸MongoDB的人,无不惊奇于它对内存的得寸进尺,至于个中缘由,我先讲讲Linux是怎么办理内存的,再说说MongoDB是怎么运用内存的,答案天然就清楚了。

 

听说带着问题学习更有用,那就先看一个MongoDB服务器的top指令成果:

shell top -p $(pidof mongod)
Mem: 32872124k total, 30065320k used, 2806804k free, 245020k buffers
Swap: 2097144k total, 100k used, 2097044k free, 26482048k cached
 VIRT RES SHR %MEM
1892g 21g 21g 69.6

这台MongoDB服务器有没有功能问题?咱们可以一边考虑一边继续阅览。

先讲讲Linux是怎么办理内存的

在Linux里(其他体系也差不多),内存有物理内存和之说,物理内存是什么天然无需解说,虚拟内存实践是物理内存的笼统,大都状况下,出于便利性的考虑,程序拜访的都是虚拟内存地址,然后操作体系会经过机制把它翻译成物理内存地址,详细阐明可以参阅和,至于程序是怎么运用虚拟内存的,可以参阅,这儿就不多费口舌了。

许多人会把虚拟内存和Swap相提并论,实践上Swap仅仅虚拟内存引申出的一种技能罢了:操作体系一旦物理内存不足,为了腾出内存空间寄存新内容,就会把当时物理内存中的内容放到交流分区里,稍后用到的时分再取回来,需求留意的是,Swap的运用或许会带来功能问题,偶然为之无需严重,糟糕的是物理内存和交流分区频频的发作数据交流,这被称之为Swap波动,一旦发作这种状况,先要清晰是什么原因形成的,假如是内存不足就好办了,加内存就可以处理,不过有的时分即使内存足够也或许会呈现这种问题,比方MySQL就有或许呈现这样的状况,一个可选的处理办法是约束运用Swap:

shell sysctl vm.swappiness=0

检查内存状况最常用的是free指令:

shell free -m
 total used free shared buffers cached
Mem: 32101 29377 2723 0 239 25880
-/+ buffers/cache: 3258 28842
Swap: 2047 0 2047

新手看到used一栏数值偏大,free一栏数值偏小,往往会以为内存要用光了。其实并非如此,之所以这样是因为每逢咱们操作文件的时分,Linux都会尽或许的把文件缓存到内存里,这样下次拜访的时分,就可以直接从内存中取成果,所以cached一栏的数值十分的大,不过不必忧虑,这部分内存是可回收的,操作体系的虚拟内存办理器会依照算法筛选冷数据。还有一个buffers,也是可回收的,不过它是保留给块设备运用的。

知道了原理,咱们就可以推算出体系可用的内存是free + buffers + cached:

shell echo $((2723 + 239 + 25880))
28842

至于体系实践运用的内存是used – buffers – cached:

shell echo $((29377 - 239 - 25880))
3258

除了free指令,还可以运用sar指令:

shell sar -r
kbmemfree kbmemused %memused kbbuffers kbcached
 3224392 29647732 90.19 246116 26070160
shell sar -W
pswpin/s pswpout/s
 0.00 0.00

期望你没有被%memused吓到,假如不幸言中,重读本文。

再说说MongoDB是怎么运用内存的

现在,MongoDB运用的是,它会把数据文件映射到内存中,假如是读操作,内存中的数据起到缓存的效果,假如是写操作,内存还可以把随机的写操作转换成次序的写操作,总归可以大幅度提高功能。MongoDB并不干与内存办理作业,而是把这些作业留给操作体系的虚拟内存办理器去处理,这样做的优点是简化了MongoDB的作业,但害处是你没有办法很便利的操控MongoDB占多大内存,走运的是虚拟内存办理器的存在让咱们大都时分并不需求关怀这个问题。

MongoDB的内存运用机制让它在缓存重建方面更有优势,简而言之:假如重启进程,那么缓存仍然有用,假如重启体系,那么可以经过复制数据文件到/dev/null的方法来重建缓存,更详细的描绘请参阅:。

有时分,即使MongoDB运用的是64位操作体系,也或许会遭受问题,呈现这种状况,八成是因为约束了内存的巨细所造成的,可以这样检查当时值:

shell ulimit -a | grep memory

大都操作体系缺省都是把它设置成unlimited的,假如你的操作体系不是,可以这样修正:

shell ulimit -m unlimited
shell ulimit -v unlimited

注:ulimit的运用是有上下文的,最好放在MongoDB的发动脚本里。

有时分,MongoDB衔接数过多的话,会,可以经过查询衔接数:

mongo db.serverStatus().connections

每个衔接都是一个线程,需求一个Stack,Linux下缺省的Stack设置一般比较大:

shell ulimit -a | grep stack
stack size (kbytes, -s) 10240

至于MongoDB实践运用的Stack巨细,可以用如下指令承认(单位:K):

shell cat /proc/$(pidof mongod)/limits | grep stack | awk -F size {print int($NF)/1024}

假如Stack过大(比方:10240K)的话没有意义,简略对照指令成果中的Size和Rss:

shell cat /proc/$(pidof mongod)/smaps | grep 10240 -A 10

一切衔接耗费的内存加起来会适当惊人,引荐把Stack设置小一点,比方说1024:

shell ulimit -s 1024

注:从开端,MongoDB会在发动时主动设置Stack。

有时分,出于某些原因,你或许想开释掉MongoDB占用的内存,不过前面说了,内存办理作业是由虚拟内存办理器操控的,幸亏可以运用MongoDB内置的指令到达意图:

mongo use admin
mongo db.runCommand({closeAllDatabases:1})

别的,经过调整内核参数也可以开释缓存:

shell sysctl vm.drop_caches=1

平常可以经过mongo指令行来监控MongoDB的内存运用状况,如下所示:

mongo db.serverStatus().mem:
 "resident" : 22346,
 "virtual" : 1938524,
 "mapped" : 962283
}

还可以经过指令来监控MongoDB的内存运用状况,如下所示:

shell mongostat
mapped vsize res faults
 940g 1893g 21.9g 0

其间内存相关字段的意义是:

mapped:映射到内存的数据巨细 visze:占用的虚拟内存巨细 res:占用的物理内存巨细

注:假如操作不能在内存中完结,成果faults列的数值不会是0,视巨细或许有功能问题。

在上面的成果中,vsize是mapped的两倍,而mapped等于数据文件的巨细,所以说vsize是数据文件的两倍,之所以会这样,是因为本例中,MongoDB敞开了,需求在内存里多映射一次数据文件,假如封闭journal,则vsize和mapped大致适当。

假如想验证这一点,可以在敞开或封闭journal后,经过pmap指令来调查文件映射状况:

shell pmap $(pidof mongod)

究竟MongoDB装备多大内存适宜?广泛点来说,多多益善,假如要切当点来说,这实践取决于你的数据及索引的巨细,内存假如可以装下悉数数据加索引是最佳状况,不过许多时分,数据都会比内存大,比方本文所触及的MongoDB实例:

mongo db.stats()
 "dataSize" : 1004862191980,
 "indexSize" : 1335929664
}

本例中索引只要1G多,内存完全能装下,而数据文件则到达了1T,估量很难找到这么大内存,此刻确保内存能装下热数据即可,至于热数据是多少,取决于详细的使用,你也可以经过调查faults的巨细来判别当时内存是否可以装下热数据,假如faults继续变大,就阐明当时内存现已不能满意热数据的巨细了。如此一来内存巨细就清晰了:内存 索引 + 热数据,最好有点充裕,究竟操作体系自身正常工作也需求耗费一部分内存。

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表娱乐之横扫全球立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章