Mongodb在NUMA機器上的優化


10gen在mongodb的部署指南上,提到了在NUMA機器上,mongodb可能會出現問題,參見:http://docs.mongodb.org/manual/administration/production-notes/#production-numa

里面引用了一篇博客,主要講MySQL的swap insanity,而mongodb也會遇到類似的問題,博客地址:http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/。

這篇博客有點長,我這里簡單概括一下。

 

對於單CPU,多核心的情況,每個核心訪問內存的速度是一樣的,這種架構稱為SMP(Symmetric multiprocessing, 對稱多處理器),又叫UMA(Uniform Memory Architecture,與NUMA相對,一致性內存訪問架構)。

 

對於多CPU,多核心的情況,如下圖:

多CPU主板

可以看到,每個CPU都有一組配套的內存槽。每個CPU訪問自身的內存插槽,速度都很快,但對於主板上的其他內存插槽,訪問速度就會下降。這種架構被稱為NUMA。

 

對於Linux來說,加載的時候就會檢測內存,計算CPU到內存的訪問開銷,將CPU和內存分成一組組的。每個進程和線程,都會繼承父進程的NUMA策略,這種策略包括這個進程/線程會在哪個CPU上運行,分配的內存應該用哪組插槽的。

 

面對內存分配,只要一經分配到指定的CPU—內存槽,就不會再挪動了。對於數據庫這類應用,理想情況下是一個單一的多線程進程,吃掉了幾乎所有的系統內存,並盡可能多的消耗其余的系統資源例如IO。

 

對於兩個CPU的NUMA架構來說,如果一個核心分配的內存超過系統內存的一半,就會出現問題。而Linux的分配策略是,首先使用CPU 0,然后再使用CPU 1。這時候就會出現一種情況,CPU 0的內存組已經率先使用完了,但系統還有很多空閑內存,都在CPU 1上。這時候,Linux會選擇將CPU 0的內存刷到磁盤上,以換取可用內存。但是,swap過程遠比跨CPU訪問內存要慢啊。這就會造成內存還沒用光,但數據庫瘋狂刷盤的現象了。

 

解決辦法是用numactl指定分配策略,將數據庫需要的內存分散在各個CPU/內存組上,保證不會出現一個核心已滿而另一個核心空閑的情況。

#numactl --interleave all command

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM