曾经心动 發表於 2019-5-16 16:41:00

Mongodb--内存管理MMAP

<p>&nbsp;    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>&nbsp; &nbsp; &nbsp;&nbsp;<strong>&nbsp;MongoDB应该分配的内存大小最好满足<span style="color: rgba(255, 0, 0, 1); background-color: rgba(255, 255, 0, 1)">内存大小&gt;索引+热数据+连接占用内存</span></strong>,通过db.stats()命令可查看到当前数据库的索引大小情况<br> &nbsp; &nbsp;&nbsp;<strong>db.stats()</strong></p>
<p>&nbsp;<em><strong>&nbsp;&nbsp; &nbsp; 下面是公司的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&gt; <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>&nbsp;</p>
<p>&nbsp;</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 &nbsp; &nbsp;</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&nbsp;/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>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>3、内存使用情况</strong></span><br>查看Linux虚拟内存管理器是否对内存做了限制,如果显示为unlimited表示无限制<br>$ &nbsp;ulimit -a | grep memory&nbsp;<br>max locked memory &nbsp; &nbsp; &nbsp; (kbytes, -l) 64<br>max memory size &nbsp; &nbsp; &nbsp; &nbsp; (kbytes, -m) unlimited<br>virtual memory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(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&gt; db.serverStatus().connections<br>{<br>"current" : 2372,<br>"available" : 48828,<br>"totalCreated" : NumberLong(185449264)<br>}</p>
<p>&nbsp;</p>
<p>Linux下缺省的Stack大小查看&nbsp;<br>$ ulimit -a | grep stack<br>stack size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(kbytes, -s) 10240</p>
<p>&nbsp;</p>
<p>MongoDB实际使用的Stack大小查看<br>可以用如下命令确认(单位:K)<br># cat /proc/$(pidof mongod)/limits | grep stack | awk -F 'size' '{print int($NF)/1024}'&nbsp;<br>10240&nbsp;</p>
<p><br>调整stack大小的方法<br>如果Stack过大,比如上述的10240K,我们可以通过以下命令调整stack大小<br># &nbsp;ulimit -s 1024<br>MongoDB释放内存的命令<br>mongo&gt; use admin<br>mongo&gt; db.runCommand({closeAllDatabases:1})&nbsp;<br>&nbsp;<br>Mongodb自带命令查看其内存使用情况<br>其中resident代表物理内存使用情况,单位为M;而virtual为虚拟内存使用情况,mapped是映射到内存的数据大小。这里虚拟内存是mapped的两倍,是因为我们开启了Journal日志,需要在内存中多映射一次,大概就是它的两倍了。如果关闭Journal日志,虚拟内存大小将和mapped大小相当。<br>bj1-farm1:PRIMARY&gt; 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>&nbsp; PID USER &nbsp; &nbsp; &nbsp;PR &nbsp;NI &nbsp;VIRT &nbsp;RES &nbsp;SHR S %CPU %MEM &nbsp; &nbsp;TIME+ &nbsp;COMMAND &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>12603 mongod &nbsp; &nbsp;20 &nbsp; 0 &nbsp;318g &nbsp;45g &nbsp;44g S 28.0 72.1 &nbsp;27230:21 mongod&nbsp;<br>free命令查看<br>而再通过free命令可查看到内存占用中有多少是因为数据缓存和cache,关于如何查看free命令,参见http://blog.csdn.net/cug_jiang126com/article/details/42266653<br>$ free<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;total &nbsp; &nbsp; &nbsp; used &nbsp; &nbsp; &nbsp; free &nbsp; &nbsp; shared &nbsp; &nbsp;buffers &nbsp; &nbsp; cached<br>Mem: &nbsp; &nbsp; &nbsp;65921032 &nbsp; 65262376 &nbsp; &nbsp; 658656 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; 274264 &nbsp; 61742808<br>-/+ buffers/cache: &nbsp; &nbsp;3245304 &nbsp; 62675728<br>Swap: &nbsp; &nbsp;100663288 &nbsp; &nbsp; &nbsp;11884 &nbsp;100651404</p>
<p><br><br></p><br><br>
来源:https://www.cnblogs.com/lemon-flm/p/10876492.html
頁: [1]
查看完整版本: Mongodb--内存管理MMAP