您好,登錄后才能下訂單哦!
mongodb在遷移數據時,通常需要導入舊數據。開始一切倒還正常,不過幾小時之后,我發現數據導入的速度下降了,同時我的腳本開始不停的拋出異常。我又重復了幾次遷移舊數據的過程,結果自然還是老樣子,但我發現每當出問題的時候,總有一個名叫irqbalance的進程CPU占用率居高不下,搜索了一下,發現很多介紹irqbalance的文章中都提及了NUMA,讓我一下子想起之前在mongodb日志中看到的警告信息,這個問題或許還真是跟NUMA有關。
mongodb日志中的警告信息:
Fri May 10 16:17:48 [initandlisten] MongoDB starting : pid=18486 port=27017 dbpath=/backup/mongodbData 64-bit host=sqcache02
Fri May 10 16:17:48 [initandlisten]
Fri May 10 16:17:48 [initandlisten] ** WARNING: You are running on a NUMA machine.
Fri May 10 16:17:48 [initandlisten] ** We suggest launching mongod like this to avoid performance problems:
Fri May 10 16:17:48 [initandlisten] ** numactl --interleave=all mongod [other options
那么NUMA到底是什么?我們來了解一下。
轉自網絡:
一、NUMA和SMP是兩種CPU相關的硬件架構。在SMP架構里面,所有的CPU爭用一個總線來訪問所有內存,優點是資源共享,而缺點是總線爭用激烈。隨著PC服務器上的CPU數量變多(不僅僅是CPU核數),總線爭用的弊端慢慢越來越明顯,于是Intel在Nehalem CPU上推出了NUMA架構,而AMD也推出了基于相同架構的Opteron CPU。
NUMA最大的特點是引入了node和distance的概念。對于CPU和內存這兩種最寶貴的硬件資源,NUMA用近乎嚴格的方式劃分了所屬的資源組(node),而每個資源組內的CPU和內存是幾乎相等。資源組的數量取決于物理CPU的個數(現有的PC server大多數有兩個物理CPU,每個CPU有4個核);distance這個概念是用來定義各個node之間調用資源的開銷,為資源調度優化算法提供數據支持。
NUMA和SMP是兩種CPU相關的硬件架構。在SMP架構里面,所有的CPU爭用一個總線來訪問所有內存,優點是資源共享,而缺點是總線爭用激烈。隨著PC服務器上的CPU數量變多(不僅僅是CPU核數),總線爭用的弊端慢慢越來越明顯,于是Intel在Nehalem CPU上推出了NUMA架構,而AMD也推出了基于相同架構的Opteron CPU。
NUMA最大的特點是引入了node和distance的概念。對于CPU和內存這兩種最寶貴的硬件資源,NUMA用近乎嚴格的方式劃分了所屬的資源組(node),而每個資源組內的CPU和內存是幾乎相等。資源組的數量取決于物理CPU的個數(現有的PC server大多數有兩個物理CPU,每個CPU有4個核);distance這個概念是用來定義各個node之間調用資源的開銷,為資源調度優化算法提供數據支持。
二、NUMA相關的策略
1、每個進程(或線程)都會從父進程繼承NUMA策略,并分配有一個優先node。如果NUMA策略允許的話,進程可以調用其他node上的資源。
2、NUMA的CPU分配策略有cpunodebind、physcpubind。cpunodebind規定進程運行在某幾個node之上,而physcpubind可以更加精細地規定運行在哪些核上。
3、NUMA的內存分配策略有localalloc、preferred、membind、interleave。localalloc規定進程從當前node上請求分配內存;而preferred比較寬松地指定了一個推薦的node來獲取內存,如果被推薦的node上沒有足夠內存,進程可以嘗試別的node。membind可以指定若干個node,進程只能從這些指定的node上請求分配內存。interleave規定進程從指定的若干個node上以RR算法交織地請求分配內存。
三、NUMA和swap的關系
NUMA的內存分配策略對于進程(或線程)之間來說,并不是公平的。在現有的Redhat Linux中,localalloc是默認的NUMA內存分配策略,這個配置選項導致資源獨占程序很容易將某個node的內存用盡。而當某個node的內存耗盡時,Linux又剛好將這個node分配給了某個需要消耗大量內存的進程(或線程),swap就妥妥地產生了。盡管此時還有很多page cache可以釋放,甚至還有很多的free內存。
四、NUMA的含義,簡單點說,在有多個物理CPU的架構下,NUMA把內存分為本地和遠程,每個物理CPU都有屬于自己的本地內存,訪問本地內存速度快于訪問遠程內存,缺省情況下,每個物理CPU只能訪問屬于自己的本地內存。對于MongoDB這種需要大內存的服務來說就可能造成內存不足,進而影響性能。
最后我們看一下,如何解決這個問題:
# echo 0 > /proc/sys/vm/zone_reclaim_mode
在啟動時,加參數
# numactl --interleave=all /data/mongodb/bin/mongod -f /app/mongodb.conf --dbpath=/data/db --fork --logpath=/data/logs/mongodb.log
這樣登陸mongodb就不會有警告信息了。
(#numactl --interleave=all mongod -f /app/mongodb.conf
forked process: 18523
all output going to: /app/mongodb/log/mongodb.log
child process started successfully, parent exiting)
***** SERVER RESTARTED *****
Fri May 10 16:33:15 [initandlisten] MongoDB starting : pid=18523 port=27017 dbpath=/backup/mongodbData 64-bit host=sqcache02
Fri May 10 16:33:15 [initandlisten] db version v2.2.6, pdfile version 4.5
Fri May 10 16:33:15 [initandlisten] git version: d626379119a6de9f2fb390780cf2fc336dfd540d
Fri May 10 16:33:15 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri
關于zone_reclaim_mode內核參數的說明,可以參考官方文檔。
注:從MongoDB1.9.2開始:MongoDB會在啟動時自動設置zone_reclaim_mode,無需手工更改。
在NUMA架構的CPU上非正常啟動mongodb會帶來什么樣的性能影響還沒做驗證,網上可以搜到一些別人使用的經驗。官方的文檔(參看MongoDB Documentation, Release 2.4.1 12.8.1 MongoDB on NUMA Hardware)中有如下說明:
簡單做下解釋,NUMA架構中每個核訪問分配給自己的內存會比分配給其他核內存要快,有下面幾種訪問控制策略:
缺省(default):總是在本地節點分配(分配在當前進程運行的節點上);
綁定(bind):強制分配到指定節點上;
交叉(interleave):在所有節點或者指定的節點上交織分配;
優先(preferred):在指定節點上分配,失敗則在其他節點上分配。
但是目前mongodb在這種架構下工作的不是很好,numactl --interleave=all就是禁用NUMA為每個核單獨分配.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。