標籤:available hardware 處理器 影響 linux
http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/
NUMA架構的CPU下,一個CPU有多個核心,那麼每個CPU成為一個NODE
關閉這個特性時
一個NODE 使用自己的本地記憶體,而盡量不去訪問其他NODE的記憶體,除非本地記憶體滿了
Linux 如何處理NUMA架構
1 把處理器分到節點(NODE),現代處理器一般是每個節點一個處理器,一個處理器上多個核
2 為每個節點串連每個處理器的本地記憶體模組
3 計算節點間的溝通成本(節點距離)
通過numactl --hardware 命令可以看到Linux如何識別NUMA架構層
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 4 5 6 7 32 33 34 35 36 37 38 39
node 0 size: 65512 MB
node 0 free: 2146 MB
node 1 cpus: 8 9 10 11 12 13 14 15 40 41 42 43 44 45 46 47
node 1 size: 65536 MB
node 1 free: 96 MB
node 2 cpus: 16 17 18 19 20 21 22 23 48 49 50 51 52 53 54 55
node 2 size: 65536 MB
node 2 free: 32362 MB
node 3 cpus: 24 25 26 27 28 29 30 31 56 57 58 59 60 61 62 63
node 3 size: 65536 MB
node 3 free: 21805 MB
node distances:
node 0 1 2 3
0: 10 11 11 11
1: 11 10 11 11
2: 11 11 10 11
3: 11 11 11 10
記憶體是平均分配到每個節點的
# Linux 如何處理資源分派
每個進程和線程繼承父親的NUMA策略.這個策略可以基於每個線程修改.
策略定義了一個進程允許被哪個節點甚至那個核心調度.
每個線程最初配指派給最"適合"的節點運行.線程也可以在其他地方運行,但是調度器試圖確保現場運行在最優節點
預設情況下,記憶體的分配被指派到特定的節點上,即這個線程"當前"啟動並執行節點.
在UMA/SMP 架構下,記憶體是平等對待的,而在NUMA下,分配其他節點的記憶體意味著cache的延遲和效能的下降
記憶體一旦分配到一個節點上,就不會移動到另一個節點,不管系統的需求,它會永遠呆在那個節點上.
任何進程的NUMA策略可以被修改,通過numactl作為程式的封裝,也可以使用 libnuma 編寫代碼管理NUMA策略.
例如使用numactl作為程式的封裝:
1 使用指定策略分配記憶體:
使用"當前"節點,--localalloc參數指定,這是預設的模式
優先使用一個節點,但也可以使用其他節點,--preferred=node參數
永遠使用一個節點或一組節點, --membind=nodes
交叉,輪詢所有節點 --interleaved=all 或者 --interleaved=nodes
2 程式運行節點的選擇
指定節點(--cpunodebind=nodes) 或者 一個核心或一組核心 (--physcpubind=cpus)
NUMA 對 MySQL 和 InnoDB 的意義
對於InnoDB和大多數資料庫伺服器(如Oracle),他們在Linux上的工作方式是,巨大的單一進程,帶有多線程.
在NUMA架構下,記憶體被指派到不同的節點上,當你分配了系統50%以上的記憶體給一個進程,這就不是一個節點內能完成的事情了.
當不同的查詢同時運行時,每個處理器都無法優先地去訪問一個特定查詢需要記憶體
事實證明這是一個很重要的問題.通過/proc/pid/numa_maps可以看到mysqld分配的所有記憶體,你會發現一個有趣的現象
如果你尋找anon=size的值,
這是其中一行的值
7ecf14000000 default anon=3584 dirty=3584 active=1024 N1=3584
7ecf14000000 虛擬記憶體地址
default NUMA 策略
anon=number 匿名頁面的數量
dirty 髒頁,被修改的頁
通常分配給進程的頁總是使用的,因此都是髒的,但是由於fork,進程會有很多copy-on-write的頁面的映射,他們不是髒的
swapcache=number
active 這個列出現,表示多少頁面出現在活動列表,同時意味著還有一些不活躍的頁面,它們將要被swapper換頁出去
N0 and N1 每個節點的頁面
通過一個指令碼,可以統計出所有記憶體的情況
perl /data0/script/numa-maps-summary.pl < /proc/4417/numa_maps
N0 : 392133 ( 1.50 GB)
N1 : 792466 ( 3.02 GB)
N2 : 531028 ( 2.03 GB)
N3 : 3743392 ( 14.28 GB)
active : 4314131 ( 16.46 GB)
anon : 5457149 ( 20.82 GB)
dirty : 5456665 ( 20.82 GB)
mapmax : 268 ( 0.00 GB)
mapped : 1930 ( 0.01 GB)
swapcache : 484 ( 0.00 GB)
讀取/proc/pid/numa_maps的資訊會阻塞進程
http://blog.wl0.org/2012/09/checking-procnuma_maps-can-be-dangerous-for-mysql-client-connections/
不但是mysql 還有mangodb
根據官方文檔的解釋,Linux, NUMA, MongoDB 這三者不是很和諧,如果當前硬體是 NUMA 的,可以把它給關了:
# numactl --interleave=all sudo -u mongodb mongod --port xxx --logappend --logpath yyy --dbpath zzz
(vm.overcommit_ratio = 100, vm.overcommit_memory = 2)
vm.zone_reclaim_mode 設定為 0。
系統給 NUMA node 分配記憶體,如果 NUMA node 已經滿了,這時候,系統會為本地的 NUMA node 回收記憶體而不是將多出來的記憶體給 remote NUMA node,這樣整體的效能會更好,但是在某些情況下,給 remote NUMA node 分配記憶體會比回收本地的 NUMA node 更好,這時候就需要將 zone_reclaim_mode 給關閉了
numactl --interleave all
NUMA對MySQL InnoDB的效能影響