MongoDB使用的是内存映射存储引擎,即Memory Mapped Storage Engine,简称MMAP。

    MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的信息位置就会在内存中有对应的地址空间,这时对文件的读写可以直接用指针来做,而不需要read/write函数了,但这并不代表将文件map到物理内存,只有访问到这块数据时才会被操作系统以Page的方式换到物理内存。MongoDB将内存管理工作交给操作系统的虚拟内存管理器来完成,这样就大大简化了MongoDB的工作,同时操作系统会将数据刷新保存到磁盘上。

  

  其实,从数据存储原理来看,我更倾向于将mongodb归类为硬盘数据库,但是使用了mmap作为加速的手段而已。

 MongoDB应该分配的内存大小最好满足内存大小>索引+热数据+连接占用内存,通过db.stats()命令可查看到当前数据库的索引大小情况
     db.stats()

     下面是公司的MongoDB存储了14亿数据,占1.4T存储空间

shard1:SECONDARY> db.stats()
{
"db" : "database",            // 当前使用的数据库 
"collections" : 662,       // 多少张表
"objects" : 1405948982,         // 所有表的多少条数据   -- 14.05亿
"avgObjSize" : 1134.649427176014, // 平均每条数据大小     
"dataSize" : 1595259207065,      // 总数据大小         -- 1.485TB
"storageSize" : 768647647232,     // 所有数据占磁盘的大小   -- 715.85G
"numExtents" : 0,
"indexes" : 1098,            // 索引数量
"indexSize" : 173431967744,      // 索引大小          -- 160G
"ok" : 1
}

2、 修改MongoDB使用的内存大小

  从3.4版本开始,默认情况下,WieldGigd内部缓存将使用下面2种中更大的一种:50% of (RAM - 1 GB) 和256 MB。通过文件系统缓存,MongoDB的自动使用未被wiredtiger缓存或由其他进程使用所有可用内存。调整WiredTiger内部缓存的方法:    storage.wiredTiger.engineConfig.cacheSizeGB 和 --wiredTigerCacheSizeGB

  看来不设置的话,默认会使用50% of (RAM - 1 GB)的内存。于是在配置文件设置了storage.wiredTiger.engineConfig.cacheSizeGB为0.5,也就是500M,再看测试结果:

  vim /etc/mongod.conf

storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
# engine:
# mmapv1:
wiredTiger:
engineConfig:
cacheSizeGB: 0.5

可以看到,MongoDB所占的物理内存稳定在了630M左右,说明设置确实生效了。

3、内存使用情况
查看Linux虚拟内存管理器是否对内存做了限制,如果显示为unlimited表示无限制
[jiangjianjian@f1-mongo1 ~]$  ulimit -a | grep memory 
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
virtual memory          (kbytes, -v) unlimited
修改虚拟内存限制
[jiangjianjian@f1-mongo1 ~]$ ulimit -m unlimited
[jiangjianjian@f1-mongo1 ~]$ ulimit -v unlimited

查看当前MongoDB的连接数
mongo中每一个连接都是一个线程,需要一个stack,从结果中可看到当前连接数为2372,最大连接数为51200
bj1-farm1:PRIMARY> db.serverStatus().connections
{
"current" : 2372,
"available" : 48828,
"totalCreated" : NumberLong(185449264)
}

Linux下缺省的Stack大小查看 
[jiangjianjian@f1-mongo1 ~]$ ulimit -a | grep stack
stack size              (kbytes, -s) 10240

MongoDB实际使用的Stack大小查看
可以用如下命令确认(单位:K)
[root@f1-mongo1 journal]# cat /proc/$(pidof mongod)/limits | grep stack | awk -F 'size' '{print int($NF)/1024}' 
10240

调整stack大小的方法
如果Stack过大,比如上述的10240K,我们可以通过以下命令调整stack大小
[root@f1-mongo1 journal]#  ulimit -s 1024
MongoDB释放内存的命令
mongo> use admin
mongo> db.runCommand({closeAllDatabases:1}) 
 
Mongodb自带命令查看其内存使用情况
其中resident代表物理内存使用情况,单位为M;而virtual为虚拟内存使用情况,mapped是映射到内存的数据大小。这里虚拟内存是mapped的两倍,是因为我们开启了Journal日志,需要在内存中多映射一次,大概就是它的两倍了。如果关闭Journal日志,虚拟内存大小将和mapped大小相当。
bj1-farm1:PRIMARY> db.serverStatus().mem
{
"bits" : 64,
"resident" : 46662,
"virtual" : 326198,
"supported" : true,
"mapped" : 161399,
"mappedWithJournal" : 322798
}

top命令查看
这里还可以通过top命令观察mongodb的内存使用情况,如下图,可看到其中的VIRT和RES与上述命令的结果一样
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                    
12603 mongod    20   0  318g  45g  44g S 28.0 72.1  27230:21 mongod 
free命令查看
而再通过free命令可查看到内存占用中有多少是因为数据缓存和cache,关于如何查看free命令,参见http://blog.csdn.net/cug_jiang126com/article/details/42266653
[jiangjianjian@f1-mongo1 ~]$ free
             total       used       free     shared    buffers     cached
Mem:      65921032   65262376     658656          0     274264   61742808
-/+ buffers/cache:    3245304   62675728
Swap:    100663288      11884  100651404

Mongodb--内存管理MMAP的更多相关文章

  1. Mongodb内存管理和使用情况查询

    overview MongoDB使用的是内存映射存储引擎,即Memory Mapped Storage Engine,简称MMAP.MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的 ...

  2. MongoDB内存管理机制

    目前,MongoDB使用的是内存映射存储引擎,它会把磁盘IO操作转换成内存操作,如果是读操作,内存中的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺序的写操作,总之可以大幅度提升性 ...

  3. MongoDB源码概述——内存管理和存储引擎

    原文地址:http://creator.cnblogs.com/ 数据存储: 之前在介绍Journal的时候有说到为什么MongoDB会先把数据放入内存,而不是直接持久化到数据库存储文件,这与Mong ...

  4. Linux内存管理 (9)mmap

    专题:Linux内存管理专题 关键词:文件映射.匿名映射.私有映射.共享映射 mmap/munmap是常用的一个系统调用,使用场景是:分配内存.读写大文件.连接动态库文件.多进程间共享内存. 更详细解 ...

  5. Linux内存管理 (9)mmap(补充)

    之前写过一篇简单的介绍mmap()/munmap()的文章<Linux内存管理 (9)mmap>,比较单薄,这里详细的梳理一下. 从常用的使用者角度介绍两个函数的使用:然后重点是分析内核的 ...

  6. Linux内存管理之mmap详解

    转发之:http://blog.chinaunix.net/uid-26669729-id-3077015.html Linux内存管理之mmap详解 一. mmap系统调用 1. mmap系统调用  ...

  7. 动态内存管理详解:malloc/free/new/delete/brk/mmap

    c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...

  8. 动态内存管理:malloc/free/new/delete/brk/mmap

    这是我去腾讯面试的时候遇到的一个问题——malloc()是如何申请内存的? c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, c ...

  9. 系统调用与内存管理(sbrk、brk、mmap、munmap)(转)

    一.系统调用(System Call):在Linux中,4G内存可分为两部分——内核空间1G(3~4G)与用户空间3G(0~3G),我们通常写的C代码都是在对用户空间即0~3G的内存进行操作.而且,用 ...

  10. Linux 内存管理之mmap详解

    找了好多,最后发现下面这篇时讲的比较通俗易懂的. Linux内存管理之mmap详解-heavent2010-ChinaUnix博客 http://blog.chinaunix.net/uid-2666 ...

随机推荐

  1. HTTP 状态码及含义

    来自 Koa.js 官方文档中关于设置请求响应的部分 response.status=,列出了从 1xx ~ 5xx HTTP 状态码及含义,现摘录如下: 100 "continue&quo ...

  2. 全栈工程师对Python面试中is和==区别的详细解说!看完真的学到了!

    面试实习生的时候,当问到 is 和 == 的区别时,很多同学都答不上来,搞不清两者什么时候返回一致,什么时候返回不一致.本文我们来看一下这两者的区别. 我们先来看几个例子: a = "hel ...

  3. ThreadLocal(线程本地存储)

    1. ThreadLocal,即线程本地变量或线程本地存储. threadlocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的 ...

  4. elasticsearch 心得

    1.es 一台机器一般为一个节点.一台机器不设置的情况下是无法创建副本集的,副本集和主本必须不在一个节点下,方便故障转移等 2.es7.x后一个索引后只能创建一个类型,可以通过修改更改 出现这个的原因 ...

  5. ES6入门系列 ----- 使用Proxy 实现观察者模式

    观察者模式是指函数自动观察数据对象的变化, 一旦对象有变化,函数就会自动执行. 它定义了一种一对多的依赖关系,我们用Proxy来实现一个简单的观察者模式(PS: 初学我们认为 观察者模式 == 发布订 ...

  6. STM32 掉电检测程序

    当VDD下降到PVD阀值以下或当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断 void PVD_IRQHandler(void) { led_ctrl ...

  7. 打开Visual Studio 2017报错:未能正确加载“VSTS for Database Professionals Sql Server Data-tier Application”包

    出现如下错误 解决办法 > cmd > regsvr32 %windir%\system32\jscript.dll

  8. 微信小程序json与xml互相转换

    1.首先在目录结构中引入必要的js文件 https://files.cnblogs.com/files/qianyou304/x2j.rar 2.js中代码如下:(部分)json 2 xml var ...

  9. MVC 身份证图像识别(调用dll)

    源码下载 -> 提取码 QQ505645074 Index.cshtml <!DOCTYPE html> <html> <head> <meta cha ...

  10. scrapy简单使用方法

    scrapy简单使用方法 1.创建项目:scrapy startproject 项目名例如:scrapy startproject baike windows下,cmd进入项目路径例如d:\pytho ...