• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            攀升·Uranus


            Something Different,Something New
            數據加載中……

            (轉)MongoDB與內存

            @import url(http://www.shnenglu.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

            MongoDB與內存

            但凡初次接觸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里(別的系統也差不多),內存有物理內存和虛擬內存之說,物理內存是什么自然無需解釋,虛擬內存實際是物理內存的抽象,多數情況下,出于方便性的考慮,程序訪問的都是虛擬內存地址,然后操作系統會通過Page Table機制把它翻譯成物理內存地址,詳細說明可以參考Understanding MemoryUnderstanding Virtual Memory,至于程序是如何使用虛擬內存的,可以參考Playing with Virtual Memory,這里就不多費口舌了。

            很多人會把虛擬內存和Swap混為一談,實際上Swap只是虛擬內存引申出的一種技術而已:操作系統一旦物理內存不足,為了騰出內存空間存放新內容,就會把當前物理內存中的內容放到交換分區里,稍后用到的時候再取回來,需要注意的是,Swap的使用可能會帶來性能問題,偶爾為之無需緊張,糟糕的是物理內存和交換分區頻繁的發生數據交換,這被稱之為Swap顛簸,一旦發生這種情況,先要明確是什么原因造成的,如果是內存不足就好辦了,加內存就可以解決,不過有的時候即使內存充足也可能會出現這種問題,比如MySQL就有可能出現這樣的情況,一個可選的解決方法是限制使用Swap:

            shell> sysctl -w 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一欄的數值非常的大,不過不用擔心,這部分內存是可回收的,操作系統的虛擬內存管理器會按照LRU算法淘汰冷數據。還有一個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的方式來重建緩存,更詳細的描述請參考:Cache Reheating – Not to be Ignored

            有時候,即便MongoDB使用的是64位操作系統,也可能會遭遇OOM問題,出現這種情況,多半是因為限制了內存的大小所致,可以這樣查看當前值:

            shell> ulimit -a | grep memory

            多數操作系統缺省都是把它設置成unlimited的,如果你的操作系統不是,可以這樣修改:

            shell> ulimit -m unlimited
            shell> ulimit -v unlimited

            注:ulimit的使用是有上下文的,最好放在MongoDB的啟動腳本里。

            有時候,MongoDB連接數過多的話,會拖累性能,可以通過serverStatus查詢連接數:

            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

            注:從MongoDB1.8.3開始,MongoDB會在啟動時自動設置Stack。

            有時候,出于某些原因,你可能想釋放掉MongoDB占用的內存,不過前面說了,內存管理工作是由虛擬內存管理器控制的,幸好可以使用MongoDB內置的closeAllDatabases命令達到目的:

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

            另外,通過調整內核參數drop_caches也可以釋放緩存:

            shell> sysctl -w vm.drop_caches=1

            平時可以通過mongo命令行來監控MongoDB的內存使用情況,如下所示:

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

            還可以通過mongostat命令來監控MongoDB的內存使用情況,如下所示:

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

            其中內存相關字段的含義是:

            • mapped:映射到內存的數據大小
            • visze:占用的虛擬內存大小
            • res:占用的物理內存大小

            注:如果操作不能在內存中完成,結果faults列的數值不會是0,視大小可能有性能問題。

            在上面的結果中,vsize是mapped的兩倍,而mapped等于數據文件的大小,所以說vsize是數據文件的兩倍,之所以會這樣,是因為本例中,MongoDB開啟了journal,需要在內存里多映射一次數據文件,如果關閉journal,則vsize和mapped大致相當。

            如果想驗證這一點,可以在開啟或關閉journal后,通過pmap命令來觀察文件映射情況:

            shell> pmap $(pidof mongod)

            到底MongoDB配備多大內存合適?寬泛點來說,多多益善,如果要確切點來說,這實際取決于你的數據及索引的大小,內存如果能夠裝下全部數據加索引是最佳情況,不過很多時候,數據都會比內存大,比如本文所涉及的MongoDB實例:

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

            本例中索引只有1G多,內存完全能裝下,而數據文件則達到了1T,估計很難找到這么大內存,此時保證內存能裝下熱數據即可,至于熱數據是多少,取決于具體的應用,你也可以通過觀察faults的大小來判斷當前內存是否能夠裝下熱數據,如果faults持續變大,就說明當前內存已經不能滿足熱數據的大小了。如此一來內存大小就明確了:內存 > 索引 + 熱數據,最好有點富余,畢竟操作系統本身正常運轉也需要消耗一部分內存。

            關于MongoDB與內存的話題,大家還可以參考官方文檔中的相關介紹。

            @import url(http://www.shnenglu.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

            posted on 2012-08-06 13:36 攀升 閱讀(1802) 評論(0)  編輯 收藏 引用 所屬分類: Linux

            日韩av无码久久精品免费| 思思久久好好热精品国产| 久久精品www人人爽人人| 国产一级持黄大片99久久| 狠狠色伊人久久精品综合网| 色8激情欧美成人久久综合电| 色诱久久av| 亚洲精品无码久久久久| 精品综合久久久久久88小说| 久久夜色撩人精品国产小说| 久久国产精品99精品国产| 久久亚洲AV无码西西人体| 久久永久免费人妻精品下载| 久久久久亚洲精品天堂久久久久久 | 老司机午夜网站国内精品久久久久久久久| 久久综合狠狠综合久久97色| 无码久久精品国产亚洲Av影片| 国内精品久久久久久久亚洲| 久久无码人妻一区二区三区午夜 | 亚洲va久久久噜噜噜久久狠狠 | 99久久这里只有精品| 理论片午午伦夜理片久久| 一级做a爰片久久毛片人呢| 99热成人精品热久久669| 久久99这里只有精品国产| 久久精品女人天堂AV麻| 777久久精品一区二区三区无码| 日韩人妻无码精品久久免费一 | 性欧美大战久久久久久久| 麻豆精品久久精品色综合| 77777亚洲午夜久久多喷| 久久无码AV一区二区三区| 久久一区二区三区免费| 国产亚州精品女人久久久久久| 久久精品亚洲乱码伦伦中文| 91久久精品国产91性色也| 久久精品成人免费看| 久久精品草草草| 欧美精品一区二区精品久久| 国产精品久久久久久久午夜片 | 久久香蕉国产线看观看99|