作者:qccz123456
來源:CSDN
原文:Linux工具之numactl
一、NUMA簡介
NUMA(Non-Uniform Memory Access)字面直譯爲“非一致性內存訪問”,對於Linux內核來說最早出現在2.6.7版本上。這種特性對於當下大內存+多CPU爲潮流的X86平臺來說確實會有不少的性能提升,但相反的,如果配置不當的話,也是一個很大的坑。本文就從頭開始說說Linux下關於CPU NUMA特性的配置和調優。
最早Intel在Nehalem架構上實現了NUMA,取代了在此之前一直使用的FSB前端總線的架構,用以對抗AMD的HyperTransport技術。一方面這個架構的特點是內存控制器從傳統的北橋中移到了CPU中,排除了商業戰略方向的考慮之外,這樣做的方法同樣是爲了實現NUMA。
在SMP多CPU架構中,傳統上多CPU對於內存的訪問是總線方式。是總線就會存在資源爭用和一致性問題,而且如果不斷的增加CPU數量,總線的爭用會愈演愈烈,這就體現在4核CPU的跑分性能達不到2核CPU的2倍,甚至1.5倍!理論上來說這種方式實現12core以上的CPU已經沒有太大的意義。
Intel的NUMA解決方案,Litrin始終認爲它來自本家的安藤。他的模型有點類似於MapReduce。放棄總線的訪問方式,將CPU劃分到多個Node中,每個node有自己獨立的內存空間。各個node之間通過高速互聯通訊,通訊通道被成爲QuickPath Interconnect即QPI。
這個架構帶來的問題也很明顯,如果一個進程所需的內存超過了node的邊界,那就意味着需要通過QPI獲取另一node中的資源,儘管QPI的理論帶寬遠高於傳統的FSB,比如當下流行的內存數據庫,在這種情況下就很被動了。
二、numactl
Linux提供了一個一個手工調優的命令numactl(默認不安裝),在Ubuntu上的安裝命令如下:
sudo apt install numactl
首先你可以通過它查看系統的numa狀態:
numactl --hardware
運行得到如下的結果:
-
available: 2 nodes (0-1)
-
node 0 cpus: 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23
-
node 0 size: 131037 MB
-
node 0 free: 3019 MB
-
node 1 cpus: 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31
-
node 1 size: 131071 MB
-
node 1 free: 9799 MB
-
node distances:
-
node 0 1
-
0: 10 20
-
1: 20 10
可以看到,此係統共有2個node,各領取16個CPU和128G內存。
這裏假設我要執行一個java param命令,此命令需要120G內存,一個python param命令,需要16G內存。最好的優化方案時python在node0中執行,而java在node1中執行,那命令是:
-
numactl --cpubind=0 --membind=0 python param
-
numactl --cpubind=1 --membind=1 java param
當然,也可以自找沒趣:
numactl --cpubind=0 --membind=0,1 java param
對於一口氣吃掉內存大半的MongoDB,我的配置是:
numactl --interleave=all mongod -f /etc/mongod.conf
即分配所有的node供其使用,這也是官方推薦的用法。
通過numastat命令可以查看numa狀態:
numastat
得到的結果如下所示:
-
node0 node1
-
numa_hit 1775216830 6808979012
-
numa_miss 4091495 494235148
-
numa_foreign 494235148 4091495
-
interleave_hit 52909 53004
-
local_node 1775205816 6808927908
-
other_node 4102509 494286252
other_node過高意味着需要重新規劃numa。
三、NUNA與SMP
NUMA(Non-Uniform Memory Access,非一致性內存訪問)和SMP(Symmetric Multi-Processor,對稱多處理器系統)是兩種不同的CPU硬件體系架構。
SMP的主要特徵是共享,所有的CPU共享使用全部資源,例如內存、總線和I/O,多個CPU對稱工作,彼此之間沒有主次之分,平等地訪問共享的資源,這樣勢必引入資源的競爭問題,從而導致它的擴展內力非常有限。
NUMA技術將CPU劃分成不同的組(Node),每個Node由多個CPU組成,並且有獨立的本地內存、I/O等資源。Node之間通過互聯模塊連接和溝通,因此除了本地內存外,每個CPU仍可以訪問遠端Node的內存,只不過效率會比訪問本地內存差一些,我們用Node之間的距離(Distance,抽象的概念)來定義各個Node之間互訪資源的開銷。
Node->Socket->Core->Processor
隨着多核技術的發展,將多個CPU封裝在一起,這個封裝被稱爲插槽Socket;Core是socket上獨立的硬件單元;通過intel的超線程HT技術進一步提升CPU的處理能力,OS看到的邏輯上的核數Processor。
socket = node
socket是物理概念,指的是主板上CPU插槽;node是邏輯概念,對應於socket。
core = 物理CPU
core是物理概念,一個獨立的硬件執行單元,對應於物理CPU;
thread = 邏輯CPU = Processor
thread是邏輯CPU,也就是Processor。
Reference
http://www.litrin.net/2017/10/31/%E6%B7%B1%E6%8C%96numa/
http://www.litrin.net/2017/08/03/numa%E5%AF%B9%E6%80%A7%E8%83%BD%E7%9A%84%E5%BD%B1%E5%93%8D/
https://blog.csdn.net/ustc_dylan/article/details/45667227
http://kodango.com/cpu-topology
https://blog.csdn.net/envy13/article/details/80241886