Mongodb--内存管理MMAP
<p> MongoDB使用的是<span style="color: rgba(255, 0, 0, 1)"><strong>内存映射存储引擎,</strong></span>即Memory Mapped Storage Engine,简称MMAP。</p><p> <strong>MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的信息位置就会在内存中有对应的地址空间,这时对文件的读写可以直接用指针来做</strong>,而不需要read/write函数了,但这并不代表将文件map到物理内存,只有访问到这块数据时才会被操作系统以Page的方式换到物理内存。MongoDB将内存管理工作交给操作系统的虚拟内存管理器来完成,这样就大大简化了MongoDB的工作,同时操作系统会将数据刷新保存到磁盘上。</p>
<p> </p>
<p> 其实,从数据存储原理来看,我更倾向于将mongodb归类为硬盘数据库,但是使用了mmap作为加速的手段而已。</p>
<p> <strong> MongoDB应该分配的内存大小最好满足<span style="color: rgba(255, 0, 0, 1); background-color: rgba(255, 255, 0, 1)">内存大小>索引+热数据+连接占用内存</span></strong>,通过db.stats()命令可查看到当前数据库的索引大小情况<br> <strong>db.stats()</strong></p>
<p> <em><strong> 下面是公司的MongoDB存储了14亿数据,占1.4T存储空间</strong></em></p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>shard1:SECONDARY> <span style="color: rgba(255, 0, 0, 1)">db.stats()</span>
{
"db" : "database", <span style="color: rgba(0, 128, 0, 1)">// 当前使用的数据库 </span>
"collections" : 662, <span style="color: rgba(0, 128, 0, 1)">// 多少张表</span>
"objects" : 1405948982, <span style="color: rgba(0, 128, 0, 1)">// 所有表的多少条数据 -- 14.05亿</span>
"avgObjSize" : 1134.649427176014, <span style="color: rgba(0, 128, 0, 1)">// 平均每条数据大小 </span>
"dataSize" : 1595259207065, <span style="color: rgba(0, 128, 0, 1)">// 总数据大小 </span> -- 1.485TB
"storageSize" : 768647647232, <span style="color: rgba(0, 128, 0, 1)">// 所有数据占磁盘的大小 -- 715.85G</span>
"numExtents" : 0,
"indexes" : 1098, <span style="color: rgba(0, 128, 0, 1)">// 索引数量</span>
"indexSize" : 173431967744, <span style="color: rgba(0, 128, 0, 1)">// 索引大小 -- 160G</span>
"ok" : 1
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p> </p>
<p> </p>
<p><strong><span style="font-size: 14pt">2、 修改MongoDB使用的内存大小</span></strong></p>
<p> 从3.4版本开始,默认情况下,<span style="color: rgba(255, 0, 0, 1)"><strong>WieldGigd内部缓存将使用下面2种中更大的一种:50% of (RAM - 1 GB) 和256 MB</strong></span>。通过文件系统缓存,MongoDB的自动使用未被wiredtiger缓存或由其他进程使用所有可用内存。调整WiredTiger内部缓存的方法: storage.wiredTiger.engineConfig.cacheSizeGB 和 --wiredTigerCacheSizeGB </p>
<p> 看来不设置的话,默认会使用50% of (RAM - 1 GB)的内存。于是在配置文件设置了storage.wiredTiger.engineConfig.cacheSizeGB为0.5,也就是500M,再看测试结果:</p>
<p><span style="color: rgba(255, 0, 0, 1)"> vim /etc/mongod.conf</span></p>
<div class="cnblogs_code">
<pre>storage:<span style="color: rgba(0, 0, 0, 1)">
dbPath</span>: /var/lib/<span style="color: rgba(0, 0, 0, 1)">mongodb
journal</span>:<span style="color: rgba(0, 0, 0, 1)">
enabled</span>:<span style="color: rgba(0, 0, 0, 1)"> true
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> engine:
# mmapv1:</span>
wiredTiger:<span style="color: rgba(0, 0, 0, 1)">
engineConfig</span>:<span style="color: rgba(0, 0, 0, 1)">
cacheSizeGB</span>: <span style="color: rgba(128, 0, 0, 1)">0.5</span></pre>
</div>
<p>可以看到,MongoDB所占的物理内存稳定在了630M左右,说明设置确实生效了。<br><br></p>
<p> </p>
<p> </p>
<p><span style="font-size: 14pt"><strong>3、内存使用情况</strong></span><br>查看Linux虚拟内存管理器是否对内存做了限制,如果显示为unlimited表示无限制<br>$ ulimit -a | grep memory <br>max locked memory (kbytes, -l) 64<br>max memory size (kbytes, -m) unlimited<br>virtual memory (kbytes, -v) unlimited<br>修改虚拟内存限制<br>$ ulimit -m unlimited<br>$ ulimit -v unlimited</p>
<p><br>查看当前MongoDB的连接数<br>mongo中每一个连接都是一个线程,需要一个stack,从结果中可看到当前连接数为2372,最大连接数为51200<br>bj1-farm1:PRIMARY> db.serverStatus().connections<br>{<br>"current" : 2372,<br>"available" : 48828,<br>"totalCreated" : NumberLong(185449264)<br>}</p>
<p> </p>
<p>Linux下缺省的Stack大小查看 <br>$ ulimit -a | grep stack<br>stack size (kbytes, -s) 10240</p>
<p> </p>
<p>MongoDB实际使用的Stack大小查看<br>可以用如下命令确认(单位:K)<br># cat /proc/$(pidof mongod)/limits | grep stack | awk -F 'size' '{print int($NF)/1024}' <br>10240 </p>
<p><br>调整stack大小的方法<br>如果Stack过大,比如上述的10240K,我们可以通过以下命令调整stack大小<br># ulimit -s 1024<br>MongoDB释放内存的命令<br>mongo> use admin<br>mongo> db.runCommand({closeAllDatabases:1}) <br> <br>Mongodb自带命令查看其内存使用情况<br>其中resident代表物理内存使用情况,单位为M;而virtual为虚拟内存使用情况,mapped是映射到内存的数据大小。这里虚拟内存是mapped的两倍,是因为我们开启了Journal日志,需要在内存中多映射一次,大概就是它的两倍了。如果关闭Journal日志,虚拟内存大小将和mapped大小相当。<br>bj1-farm1:PRIMARY> db.serverStatus().mem<br>{<br>"bits" : 64,<br>"resident" : 46662,<br>"virtual" : 326198,<br>"supported" : true,<br>"mapped" : 161399,<br>"mappedWithJournal" : 322798<br>}</p>
<p>top命令查看<br>这里还可以通过top命令观察mongodb的内存使用情况,如下图,可看到其中的VIRT和RES与上述命令的结果一样<br> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND <br>12603 mongod 20 0 318g 45g 44g S 28.0 72.1 27230:21 mongod <br>free命令查看<br>而再通过free命令可查看到内存占用中有多少是因为数据缓存和cache,关于如何查看free命令,参见http://blog.csdn.net/cug_jiang126com/article/details/42266653<br>$ free<br> total used free shared buffers cached<br>Mem: 65921032 65262376 658656 0 274264 61742808<br>-/+ buffers/cache: 3245304 62675728<br>Swap: 100663288 11884 100651404</p>
<p><br><br></p><br><br>
来源:https://www.cnblogs.com/lemon-flm/p/10876492.html
頁:
[1]