診斷 mongodb 主要故障和不穩定行為
我們有一個執行在 amazon ec2 大型 (7.5GB) ubuntu 實例上的 mongodb 實例(執行我們的 node.js 伺服器的同一台機器)。最近流量增加了很多,我們開始看到 mongodb 出現一些不穩定的行為。目前狀態:
我們注意到使用分析器的一些慢查詢:
query mydb.user 1327ms Wed Aug 01 2012 14:01:39 query:{ "_id" : ObjectId("500f45486562e7053d070363") } idhack responseLength:178 client:127.0.0.1 user:
使用者表中的條目很小,但表中有大約 5000 萬個條目。這種情況每兩分鐘就會發生一次,隨後會出現一系列緩慢的查詢。當我們使用命令行從命令行執行慢查詢時
explain()
,不會報告任何錯誤。
mongostat
告訴我:insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn set repl time 138 804 9 0 96 36 0 60.2g 121g 3.42g 2 1.8 0 0|0 1|0 93k 479k 19 fgset M 14:15:59 94 755 4 0 71 35 0 60.2g 121g 3.41g 0 1.5 0 0|0 1|0 78k 344k 19 fgset M 14:16:00 93 17 4 0 75 27 0 60.2g 121g 3.41g 0 1.2 0 0|0 1|0 24k 31k 19 fgset M 14:16:01 87 86 6 0 73 33 0 60.2g 121g 3.41g 0 0.9 0 0|0 1|0 31k 260k 19 fgset M 14:16:02 101 531 3 0 62 19 0 60.2g 121g 3.41g 0 1 0 0|0 1|0 60k 1m 19 fgset M 14:16:03 92 713 2 0 66 24 0 60.2g 121g 3.41g 1 0.9 0 0|0 0|0 72k 1m 17 fgset M 14:16:04 163 91 6 0 93 46 0 60.2g 121g 3.41g 2 9.5 0 0|0 1|0 44k 256k 17 fgset M 14:16:05 108 62 6 0 79 38 0 60.2g 121g 3.41g 4 1.2 0 0|0 1|0 32k 122k 17 fgset M 14:16:06 137 23 6 0 81 32 0 60.2g 121g 3.41g 0 2.3 0 0|0 0|0 32k 67k 17 fgset M 14:16:07
pidstat -r -p <pid> 5
告訴我:02:18:01 PM 1700 647.00 0.80 126778144 3578036 46.80 mongod 02:18:06 PM 1700 1092.00 1.20 126778144 3586364 46.91 mongod 02:18:11 PM 1700 689.60 0.20 126778144 3578912 46.81 mongod 02:18:16 PM 1700 740.80 1.20 126778144 3577652 46.79 mongod 02:18:21 PM 1700 618.60 0.20 126778144 3578100 46.80 mongod 02:18:26 PM 1700 246.00 1.00 126778144 3577392 46.79 mongod
請注意,我們的數據庫卷是單個 ext4 卷,而不是推薦的 raided 集。
我不確定下一步是如何充分理解問題以實施修復。任何輸入表示讚賞。
我必須更好地了解一段時間內的趨勢才能確定(MMS會有所幫助),但您可能會遇到一個問題,即您已達到該實例上 MongoDB 的最大常駐記憶體 - 頁面錯誤是沒那麼高,但我確實看到常駐記憶體略有下降。如果其他地方(來自另一個程序)存在記憶體壓力,您可能會從 MongoDB 中逐出頁面和/或不得不比您應該更頻繁地分頁到磁碟(EBS 上的分頁到磁碟非常慢)。
您可以做幾件事來提高 RAM 的使用效率:
- 刪除不必要的索引 - 如果使用它們只會佔用寶貴的 RAM - 刪除的好候選者是單個索引,它們是其他地方的複合索引的最左邊元素。關於可以刪除的內容,這實際上取決於您的使用情況和架構,所以我只能給出一般性建議。
- 調低EBS 卷上的預讀- 這與您將閱讀的有關調整 EBS 卷的內容相反,但是當您的訪問配置文件是隨機的而不是順序的時,預讀設置過高實際上會拖累記憶體使用。
要查看卷的預讀設置,請執行以下命令(需要 root/sudo 權限):
sudo blockdev --report
輸出將列出如下內容:
RO RA SSZ BSZ StartSec Size Device rw 256 512 4096 0 10737418240 /dev/xvda1
RA 列(256,我相信這是亞馬遜的預設值)是我們要在這裡調整的。你可以通過執行這樣的東西來做到這一點:
blockdev --setra <value> <device name>
對於上面的範例,我將從將值減半開始:
blockdev --setra 128 /dev/xvda1
如果您想了解更多資訊,我將更詳細地介紹您應該將此值設置多低以及此答案背後的原因。請注意,更改需要重新啟動 mongod 程序才能生效。
完成這兩件事後,您可能能夠從該 xlarge 實例的 RAM 中擠出更多性能。如果沒有,或者記憶體壓力來自其他地方並且提高效率還不夠,那麼是時候獲得更多 RAM。
如您所述,將 EBS 儲存升級到 RAID 卷或使用新的預置 IOPS 和 EBS 優化實例(或 SSD 集群計算節點,如果您有錢可做)將有助於“慢”部分操作(從磁碟分頁)但是沒有什麼能比記憶體操作的好處更好的了——即使磁碟子系統得到了改進,它們仍然要快一個數量級。