zoukankan      html  css  js  c++  java
  • MongoDB内存管理机制

    目前,MongoDB使用的是内存映射存储引擎,它会把磁盘IO操作转换成内存操作,如果是读操作,内存中的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺序的写操作,总之可以大幅度提升性能。MongoDB并不干涉内存管理工作,而是把这些工作留给操作系统的虚拟缓存管理器去处理,这样的好处是简化了MongoDB的工作,但坏处是你没有方法很方便的控制MongoDB占多大内存,事实上MongoDB会占用所有能用的内存,所以最好不要把别的服务和MongoDB放一起。

    有时候,即便MongoDB使用的是64位操作系统,也可能会遭遇臭名昭著的OOM问题,出现这种情况,多半是因为限制了虚拟内存的大小所致,可以这样查看当前值:

    [root@localhost bin]# ulimit -a | grep 'virtual'
    virtual memory          (kbytes, -v) unlimited
    

      


    多数操作系统缺省都是把它设置成unlimited的,如果你的操作系统不是,可以这样修改:

    [root@localhost bin]# ulimit -v unlimited
    [root@localhost bin]# 
    

      


    不过要注意的是,ulimit的使用是有上下文的,最好放在MongoDB的启动脚本里。

    另外,通过调整内核参数drop_caches也可以释放缓存:

    [root@localhost bin]# sysctl -w vm.drop_caches=1
    vm.drop_caches = 1
    

      


    平时可以通过mongo命令行来监控MongoDB的内存使用情况,如下所示:

    repl:PRIMARY> db.serverStatus().mem
    {
    	"bits" : 64,
    	"resident" : 82,
    	"virtual" : 5316,
    	"supported" : true,
    	"mapped" : 2287,
    	"mappedWithJournal" : 4574
    }
    

      


    还可以通过mongostat命令来监控MongoDB的内存使用情况,如下所示:

    [root@localhost bin]# ./mongostat
    
    mapped vsize   res faults 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
      4.2G  9.2G 84.0M      0 
    

    其中内存相关字段的含义是:
    mapped:映射到内存的数据大小
    visze:占用的虚拟内存大小
    res:实际使用的内存大小
    注:如果操作不能再内存中完成,结果faults列的数值不会是0,视大小可能有性能问题。
    在上面的结果中,vsize是mapped的两倍,而mapped等于数据文件的大小,所以说vsize是数据文件的两倍,之所以会这样,是因为本例中,MongoDB开启了journal,需要在内存里多映射一次数据文件,如果关闭journal,则vsize和mapped大致相当。
    如果想验证这一点,可以在开启或关闭journal后,通过pmap命令来观察文件映射情况:

    [root@localhost bin]# pmap $(pidof mongod)
    19300:   ./mongod --config /root/software/mongodb/mongo.conf
    0000000000400000  20396K r-x--  /root/software/mongodb/bin/mongod
    00000000019ea000    560K rw---  /root/software/mongodb/bin/mongod
    

      


    到底MongoDB配备多大内存合适?宽泛点来说,多多益善,如果要确切点来说,这实际取决于你的数据及索引的大小,内存如果能够装下全部数据加索引是最佳情况,不过很多时候,数据都会比内存大,比如本文说涉及的MongoDB实例:

    repl:PRIMARY>  db.stats()
    {
    	"db" : "admin",
    	"collections" : 0,
    	"objects" : 0,
    	"avgObjSize" : 0,
    	"dataSize" : 0,
    	"storageSize" : 0,
    	"numExtents" : 0,
    	"indexes" : 0,
    	"indexSize" : 0,
    	"fileSize" : 0,
    	"ok" : 1
    }
    

    另外实例:

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

      


    本例中索引只有1G多,内存完全能装下,而数据文件则达到了1T,估计很难找到这么大内存,此时保证内存能装下热数据即可,至于热数据有多少,这就是个比例问题了,取决于具体的应用。如此一来内存大小就明确了:内存 > 索引 + 热数据。
    关于MongoDB与内存的话题,大家还可以参考官方文档中的相关介绍。

    http://huoding.com/2011/08/19/107

  • 相关阅读:
    致虚极守静笃
    DNS 透明代理
    Java“禁止”泛型数组
    Java和C#语法对比
    JVM 内存区域 (运行时数据区域)
    Java8 使用
    G1收集器的收集原理
    BZOJ 2222: [Cqoi2006]猜数游戏【神奇的做法,傻逼题,猜结论】
    数据结构之网络流入门(Network Flow)简单小节
    BZOJ 1257: [CQOI2007]余数之和sum【神奇的做法,思维题】
  • 原文地址:https://www.cnblogs.com/xiaoit/p/4538859.html
Copyright © 2011-2022 走看看