在 Linux 系統中,為了提高文件系統性能,內核利用一部分物理內存分配出緩沖區,用於緩存系統操作和數據文件,當內核收到讀寫的請求時,內核先去緩存區找是否有請求的數據,有就直接返回,如果沒有則通過驅動程序直接操作磁盤。
內存查看
當我們使用 free -h
命令時,會顯示如下的信息:
total used free shared buff/cache available
Mem: 7.6G 166M 7.0G 8.5M 515M 7.2G
Swap: 7.9G 0B 7.9G
- total:內存總數
- used:已經使用的內存數
- free:空閑的內存數
- shared:共享內存數
- buff/cache:代表的是buff 和 cache 的內存
- available:活躍的內存
available 代表一個新的應用程序可以使用內存的估計值,它不等於 free + buff/cache
官方定義
Estimation of how much memory is available for starting new applications, without swapping. Unlike the data provided by the cache or free fields, this field takes into account page cache and also that not all reclaimable memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo,available on kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free
大致意思就是立即可以使用的內存大小。
比如:一個新的程序要運行需要的最小內存,如果 available 大於這個最小內存就可以安裝。
關系
total = used + available
手動釋放Linux 內存 cache
當在 Linux 下頻繁存取文件后,物理內存會很快被用光,當程序結束后,內存不會被正常釋放,而是一直作為 caching。
[root@localhost ~]#dd if=/dev/zero of=bigfile bs=1M count=20480 &
[1] 19883
[root@localhost ~]#free -h
total used free shared buff/cache available
Mem: 7.6G 133M 131M 8.5M 7.4G 7.2G
Swap: 7.9G 0B 7.9G
使用 dd
模擬系統讀寫,此時:
- used 為 133M
- buff/cache 為 7.4G
單從這兩項來看,內存已經被 buff/cache
耗盡。當 dd
命令執行完畢,等待一段時間 buff/cache
是否會釋放掉內存到 free
中呢?
等待一段時間,查看內存:
[root@localhost ~]#free -h
total used free shared buff/cache available
Mem: 7.6G 129M 133M 8.5M 7.4G 7.2G
Swap: 7.9G 0B 7.9G
系統並沒有自動釋放 buff/cache
那么是否能夠通過手工來進行釋放呢?
PS:在 CentOS 7.X 版本中,真正可用內存應該看 available
項。
在 /proc
目錄下除了只讀文件,在 /proc/sys/
子目錄下有很多文件內容可以進行修改,修改了這些文件可以更改內核的運行特性。寫入的格式一般為:echo N > /path/to/your/filename
如果要手動釋放buff/cache
則需要對 /proc/sys/vm/drop_caches
進行操作。
對於 /proc/sys/vm/drop_caches
官方文檔介紹:
操作如下:
[root@localhost ~]#free -h
total used free shared buff/cache available
Mem: 7.6G 128M 133M 8.5M 7.4G 7.2G
Swap: 7.9G 0B 7.9G
[root@localhost ~]#sync
[root@localhost ~]#sync
[root@localhost ~]#sync
[root@localhost ~]#free -h
total used free shared buff/cache available
Mem: 7.6G 128M 133M 8.5M 7.4G 7.2G
Swap: 7.9G 0B 7.9G
[root@localhost ~]#echo 3 > /proc/sys/vm/drop_caches
[root@localhost ~]#free -h
total used free shared buff/cache available
Mem: 7.6G 128M 7.5G 8.5M 43M 7.4G
Swap: 7.9G 0B 7.9G
通過執行: echo 3 > /proc/sys/vm/drop_caches
效果很明顯,buff/cache
釋放了內存到 free
中。
總結
手動釋放 buff/cache
只需要執行 echo 3 > /proc/sys/vm/drop_caches
就能實現,但是前提需要執行 sync 確保緩存區都寫入到磁盤,否則會造成文件的丟失等問題。
在釋放前和釋放后, available
並沒有發生太大的變化,個人認為在 CentOS 7.X 版本中,真正空閑的內存更應該是 available
稍后通過實例來說明。
手動釋放 Swap 分區內存
Swap 用途:Swap 意思是交換分區,通常我們說的虛擬內存,是從硬盤中划分出一個分區。當物理內存不夠用的時候,內核就會釋放緩存區(buffers/cache)里一些長時間不用的程序,然后將這些程序臨時放到 Swap中,也就是說如果物理內存和緩存區內存不夠用的時候,才會用到 Swap
查看了部分資料,清理 Swap 的方式比較野蠻:
swapoff -a && swapon -a
在執行該命令之前,建議多次執行 sync
避免文件的丟失。
注意:這樣清理有個前提條件,空閑的內存必須比已經使用的Swap空間要大!
這里有個配置是關於 Swap 的 /proc/sys/vm/swappiness
swappiness
值的大小對如何使用 Swap 分區有着很大的聯系。swappiness=0
的時候表示最大限度使用物理內存,然后才是 swap空間,swappiness=100
的時候表示積極的使用swap分區,並且把內存上的數據及時的搬到swap空間里面。Linux 的基本默認配置為60,具體如下:
[root@localhost ~]# sysctl -q vm.swappiness
vm.swappiness = 30
也就是說,內存在使用 100-70=30%
的時候,就開始出現有交換分區的使用。這樣會加大系統的IO,同時造成大量頁的換進換出,嚴重影響系統的性能,所以在操作系統層面,要盡可能使用內存。
臨時調整方式:
[root@localhost ~]# sysctl vm.swappiness=10
vm.swappiness = 10
[root@localhost ~]# cat /proc/sys/vm/swappiness
10
永久生效方式:
[root@localhost ~]# sysctl -q vm.swappiness
vm.swappiness = 30
[root@localhost ~]# cat /etc/sysctl.d/my-default.conf
vm.swappiness=10
[root@localhost ~]# sysctl -p /etc/sysctl.d/my-default.conf
真實案例
線上有台虛擬機跑的 mongodb 服務,查看內存如下:
[root@node3 ~]# free -h
total used free shared buff/cache available
Mem: 31G 19G 286M 10G 11G 253M
Swap: 4.0G 3.9G 54M
- used 為 19G
- buff/cache 緩存為 11G
- available 活躍可用的內存為 253M
- Swap 已用為 3.9G
對內存使用已經很誇張了, 比較慶幸的是沒有觸發 OOM killer
[root@node3 ~]# egrep -ri 'out of memory' /var/log/
[root@node3 ~]#
通過上面的理解,進行操作:
第一步:清理 buff/cache
[root@node3 ~]# free -h
total used free shared buff/cache available
Mem: 31G 19G 286M 10G 11G 253M
Swap: 4.0G 3.9G 54M
[root@node3 ~]# sync
[root@node3 ~]# sync
[root@node3 ~]# sync
[root@node3 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@node3 ~]# free -h
total used free shared buff/cache available
Mem: 31G 19G 306M 10G 11G 263M
Swap: 4.0G 3.9G 54M
可以看到這樣的操作在主機上沒有產生任何效果。
Swap 已經使用了 3.9G 而物理內存活躍可用的空閑空間為: 263M 完全不夠釋放的前提條件。因此也無法對 Swap 進行釋放。
通過 smem
查看使用 Swap的 進程:
[root@node3 ~]# smem -tp -s swap -r
PID User Command Swap USS PSS RSS
10701 root /usr/local/mongodb/bin/mong 29.18% 59.54% 59.54% 59.54%
2748 root /usr/bin/python /usr/bin/sa 0.46% 0.07% 0.07% 0.07%
2752 root /usr/bin/python /usr/bin/sa 0.45% 0.00% 0.00% 0.00%
2745 root /usr/bin/python /usr/bin/sa 0.37% 0.00% 0.00% 0.00%
871 root /usr/bin/python -Es /usr/sb 0.27% 0.00% 0.00% 0.00%
...
注意:smem 默認的單位為:KB
也可以通過 awk
統計:
for i in $( cd /proc;ls |grep "^[0-9]"|awk ' $0 >100') ;do awk '/Swap:/{a=a+$2}END{print '"$i"',a/1024"M"}' /proc/$i/smaps 2>/dev/null ; done | sort -k2nr |head
上面這台主機由於是直接將內存掛載到目錄,mongodb 數據都跑在內存中使用,確定為內存嚴重不足,最后切換到內存更大的主機上了。 個人理解:當Swap被使用時,查看 available 項,如果 available 值大於 已使用的 Swap 可以進行手動釋放內存,否則就是內存不足的表現,應當查看程序是否存在問題或者直接換更大內存的主機。
為了證明這個觀點,找了幾台虛擬節點進行實踐:
示例
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 177M 2.0G 315M 5.5G 6.9G
Swap: 4.0G 32M 4.0G
該主機運行了一個java程序,Swap used < available
滿足條件,查看 Swap 都是被那些程序在用。
[root@node1 ~]# smem -s swap -r | head -5
PID User Command Swap USS PSS RSS
873 root /usr/bin/python -Es /usr/sb 7268 3892 4453 6800
669 polkitd /usr/lib/polkit-1/polkitd - 5564 1904 2597 4628
1414 root /usr/libexec/postfix/master 932 172 240 1208
16744 nginx nginx: worker proces 928 324 422 1360
[root@node1 ~]# for i in $( cd /proc;ls |grep "^[0-9]"|awk ' $0 >100') ;do awk '/Swap:/{a=a+$2}END{print '"$i"',a/1024"M"}' /proc/$i/smaps 2>/dev/null ; done | sort -k2nr |head -5
873 7.09766M
669 5.43359M
1414 0.910156M
16744 0.90625M
1438 0.898438M
查看結果都是一些系統默認進程占用的,Swap沒有得到釋放,接下來通過手動的方式進行釋放:
[root@node1 ~]# sync && sync && sync
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 112M 2.1G 315M 5.4G 6.9G
Swap: 4.0G 32M 4.0G
[root@node1 ~]# swapoff -a
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 128M 2.1G 328M 5.4G 6.9G
Swap: 0B 0B 0B
[root@node1 ~]# swapon -a
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 131M 2.1G 328M 5.4G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# cat /etc/sysctl.d/my-default.conf
vm.swappiness=10
通過操作發現,Swap 被釋放了,內存中的 shared (共享內存)卻增長了,接下來嘗試釋放buff/cache
:
[root@node1 ~]# sync && sync && sync
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 131M 2.1G 328M 5.4G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# cat /proc/sys/vm/drop_caches
0
[root@node1 ~]# echo 3 > /proc/sys/vm/drop_caches
執行完 echo 3 > /proc/sys/vm/drop_caches
打開另一個會話持續查看內存狀態變化:
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 133M 2.3G 328M 5.2G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 133M 2.4G 328M 5.1G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 133M 3.6G 328M 3.9G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 133M 4.3G 328M 3.2G 6.9G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 117M 7.1G 328M 399M 7.1G
Swap: 4.0G 0B 4.0G
[root@node1 ~]# free -h
total used free shared buff/cache available
Mem: 7.6G 117M 7.1G 328M 399M 7.1G
Swap: 4.0G 0B 4.0G
可以發現,buff/cache
是逐漸遞減的,釋放結果:
used 從 133M 減少到 117M
free 從 2.3G 增加到 7.1G
available 從 6.9G 增加到 7.1G
最后引用別人博客的一段話,我覺得很客觀:
實際項目中告訴我們,如果因為是應用有像內存泄露、溢出的問題,從swap的使用情況是可以比較快速可以判斷的,但free上面反而比較難查看。相反,如果在這個時候,我們告訴用戶,修改系統的一個值,“可以”釋放內存,free就大了。用戶會怎么想?不會覺得操作系統“有問題”嗎?所以說,我覺得既然核心是可以快速清空buffer或cache,也不難做到(這從上面的操作中可以明顯看到),但核心並沒有這樣做(默認值是0),我們就不應該隨便去改變它。一般情況下,應用在系統上穩定運行了,free值也會保持在一個穩定值的,雖然看上去可能比較小。
當發生內存不足、應用獲取不到可用內存、OOM錯誤等問題時,還是更應該去分析應用方面的原因,如用戶量太大導致內存不足、發生應用內存溢出等情況,否則,清空buffer,強制騰出free的大小,可能只是把問題給暫時屏蔽了。
排除內存不足的情況外,除非是在軟件開發階段,需要臨時清掉buffer,以判斷應用的內存使用情況;或應用已經不再提供支持,即使應用對內存的時候確實有問題,而且無法避免的情況下,才考慮定時清空buffer。(可惜,這樣的應用通常都是運行在老的操作系統版本上,上面的操作也解決不了)。而生產環境下的服務器可以不考慮手工釋放內存,這樣會帶來更多的問題。記住內存是拿來用的,不是拿來看的。
不像windows,無論你的真實物理內存有多少,他都要拿硬盤交換文件來讀。這也就是windows為什么常常提示虛擬空間不足的原因,你們想想多無聊,在內存還有大部分的時候,拿出一部分硬盤空間來充當內存。硬盤怎么會快過內存,所以我們看linux,只要不用swap的交換空間,就不用擔心自己的內存太少。如果常常swap用很多,可能你就要考慮加物理內存了,這也是linux看內存是否夠用的標准哦。
系統初始化對Swap的優化
通過上面的實踐,總結針對 Swap 內核參數優化如下:
- 設置 vm.swappiness=10 盡量減少對 Swap 的使用;
- 通過對
/proc/sys/vm/drop_caches
值的修改實現手動釋放buff/cache
默認為0,設置為 3 則釋放; - 如果
available > Swap[used]
則可以通過swappoff -a && swapon -a
來強制釋放Swap
注意:在執行手動釋放內存時候,要多次執行sync
!
接下來在介紹 一種對 Swap 的優化方案。
Numa
numa 是一種關於多個cpu如何訪問內存的架構模型,現在的cpu 基本都是numa架構,linux內核2.5開始支持numa。
numa架構簡單的來說,一個物理cpu(一般包含多個邏輯cpu或多個核心)構成一個node,這個node不僅包括cpu,還包括一組內存插槽,也就是說一個物理cpu以及一塊內存構成了一個node。每個node可以訪問自己node下的內存,也可以訪問其他node的內存,但是訪問速度是不一樣的,自己node下的更快。numactl --hardware命令可以查看node狀況。
安裝 numactl
:
[root@localhost ~]# yum install numactl -y
# 列舉系統上的NUMA節點及內存信息
[root@localhost ~]# numactl --hardware
Redhat 或者 Centos 系統中可以通過命令判斷BIOS 層是否開啟 NUMA
egrep -i numa /var/log/dmesg
如果輸出的結果為:No NUMA configuration found
說明 numa 為 disable
如果不是上面內容說明numa為enable,例如顯示:Enabling automatic NUMA balancing.
可以使用 lscpu
查看 NUMA 的分布:


當發現numa_miss 數值比較高時,說明需要對分配策略進行調整。例如將制定進程關聯到指定個的cpu上,從而提高內存命中率。
numa_hit:成功再本地node命中的次數。
numa_miss:本因分配在其他NODE的內存,由於其他節點內存太少,導致內存分配在本node的頁數量。
numa_foreign:初始分配在本地,最后分配在其他節點的葉數量。每個numa_foreign對應numa_miss事件。
interleave_hit:interleave策略頁成功分配到這個節點。
local_node:本節點進程成功在本節點分配頁數量。
other_node:其他節點運行的進程,在本節分配的頁數量。
現在的機器上都是有多個CPU和多個內存塊的。以前我們都是將內存塊看成是一大塊內存,所有CPU到這個共享內存的訪問消息是一樣的。這就是之前普遍使用的SMP模型。但是隨着處理器的增加,共享內存可能會導致內存訪問沖突越來越厲害,且如果內存訪問達到瓶頸的時候,性能就不能隨之增加。NUMA(Non-Uniform Memory Access)就是這樣的環境下引入的一個模型。比如一台機器是有2個處理器,有4個內存塊。我們將1個處理器和兩個內存塊合起來,稱為一個NUMA node,這樣這個機器就會有兩個NUMA node。在物理分布上,NUMA node的處理器和內存塊的物理距離更小,因此訪問也更快。比如這台機器會分左右兩個處理器(cpu1, cpu2),在每個處理器兩邊放兩個內存塊(memory1.1, memory1.2, memory2.1,memory2.2),這樣NUMA node1的cpu1訪問memory1.1和memory1.2就比訪問memory2.1和memory2.2更快。所以使用NUMA的模式如果能盡量保證本node內的CPU只訪問本node內的內存塊,那這樣的效率就是最高的。
這里有一個 numa 的陷阱,現象就是當你的服務器還有內存的時候,發現它已經在開始使用 Swap 了, 甚至已經導致機器出現停滯的想象。這個就是這個就有可能是由於numa的限制,如果一個進程限制它只能使用自己的numa節點的內存,那么當自身numa node內存使用光之后,就不會去使用其他numa node的內存了,會開始使用swap,甚至更糟的情況,機器沒有設置swap的時候,可能會直接死機!所以可以使用numactl --interleave=all來取消numa node的限制。
如果你的程序是會占用大規模內存的,你大多應該選擇關閉numa node的限制(或從硬件關閉numa)。因為這個時候你的程序很有幾率會碰到numa陷阱。另外,如果你的程序並不占用大內存,而是要求更快的程序運行時間。你大多應該選擇限制只訪問本numa node的方法來進行處理。
內核參數:
[root@localhost ~]#sysctl -a | egrep overcommit_memory
vm.overcommit_memory = 0
該參數為內存分配策略
可選值:0、1、2 默認為 0
0:表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
1:表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2:表示內核允許分配超過所有物理內存和交換空間總和的內存
[root@localhost ~]#sysctl -a | egrep zone_reclaim_mode
vm.zone_reclaim_mode = 0
可選值:0 , 1
當某個節點可用內存不足時:
1:如果為0的話,那么系統會傾向於從其他節點分配內存
2:如果為1的話,那么系統會傾向於從本地節點回收Cache內存多數時候
Cache 對性能很重要,所以0是一個更好的選擇,不需要修改。
Mongodb 的 NUMA 問題
mongodb日志顯示如下:
WARNING: You are running on a NUMA machine.
We suggest launching mongod like this to avoid performance problems:
numactl –interleave=all mongod [other options]
解決方案:臨時修改numa內存分配策略為 interleave=all (在所有node節點進行交織分配的策略):
- 在原啟動命令前加 numactl --interleave=all
如:numactl --interleave=all ${MONGODB_HOME}/bin/mongod --config conf/mongodb.conf
- 修改內核參數
echo 0 > /proc/sys/vm/zone_reclaim_mode ; echo "vm.zone_reclaim_mode = 0" >> /etc/sysctl.conf
深入NUMA
NUMA 和 SMP |
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 的相關策略 |
- 每個進程(或線程)都會從父進程繼承NUMA策略,並分配有一個優先node。如果NUMA策略允許的話,進程可以調用其他node上的資源。
- NUMA的CPU分配策略有cpunodebind、physcpubind。cpunodebind規定進程運行在某幾個node之上,而physcpubind可以更加精細地規定運行在哪些核上。
- NUMA的內存分配策略有localalloc、preferred、membind、interleave。
localalloc:規定進程從當前node上請求分配內存;
preferred:比較寬松地指定了一個推薦的node來獲取內存,如果被推薦的node上沒有足夠內存,進程可以嘗試別的node。
membind:可以指定若干個node,進程只能從這些指定的node上請求分配內存。
interleave:規定進程從指定的若干個node上以RR(Round Robin 輪詢調度)算法交織地請求分配內存。
修改NUMA 內存配置命令如下:
memory policy is --interleave | -i, --preferred | -p, --membind | -m, --localalloc | -l
NUMA 默認的內存分配策略是優先在進程所在CPU 的本地內存中分配,會導致CPU節點之間內存分配不均衡,當某個CPU節點的內存不足時,會導致Swap產生,而不是從遠程節點分配內存。這就是所謂的 Swap Insanity
現象。
MySQL采用了線程模式,對於NUMA特性的支持並不好,如果單機只運行一個MySQL實例,我們可以選擇關閉NUMA,關閉的方法有三種:
- 硬件層,在BIOS 中設置關閉;
- OS內核,啟動時設置
numa=off
; - 可以用
numactl
命令將內存分配策略修改為interleave
(交叉)
如果單機運行多個MySQL實例,我們可以將MySQL綁定在不同的CPU節點上,並且采用綁定的內存分配策略,強制在本節點內分配內存,這樣既可以充分利用硬件的NUMA特性,又避免了單實例MySQL對多核CPU利用率不高的問題
NUMA 和 Swap 的關系 |
NUMA 的內存分配策略對於進程(或線程)之間來說,並不是公平的。在現在的 Redhat Linux中, localalloc 是默認的NUMA 內存分配策略,這個配置選項導致資源獨占程序很容易將某個 node 的內存用盡。而當某個 node 的內存耗盡時,Linux 又剛好將這個 node 分配給了某個需要大量內存的進程(或線程),swap 就妥妥的產生了。盡管此時還有很多 page cache 可以釋放,甚至還有很多的 free 內存。
對於 MySQL 來說,解決Swap的問題很簡單:只要啟動MySQL之前使用 numactl --interleave
來修改 NUMA 策略即可。
NUMA 之 CPU 優化
現在的服務器CPU 新增了一項新功能:CPU節能。
[root@mongodb ~]# lscpu | egrep "model name"
[root@mongodb ~]# lscpu | egrep -i "model name"
Model name: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz
[root@mongodb ~]# cat /proc/cpuinfo | egrep -i mhz
cpu MHz : 1200.000
cpu MHz : 1200.000
cpu MHz : 1200.000
cpu MHz : 1200.000
cpu MHz : 1200.000
cpu MHz : 1440.000
cpu MHz : 1200.000
...
CPU 實際運行的頻率和標稱的頻率不符,這就是CPU啟用了節能模式。操作系統和CPU 硬件配合,系統不繁忙的時候,為了節約電能和降低溫度,它會將 CPU降頻。這對於需要高性能的服務來說,簡直是災難,比如 MySQL。
為了保證服務能夠充分利用cpu的資源,建議設置CPU 為最大性能模式。這個設置可以在 BIOS 和操作系統中設置。最好的方式是在 BIOS 中設置,更好更徹底。
在操作系統中,CPU 設置為高性能:
cpupower -c all frequency-set -g performance
再來看看內存方面, 有哪些可以優化。
可以設置的內存分配方式,目前支持的方式包括:
--interleave=nodes
--membind=nodes
--cpunodebind=nodes
--physcpubind=cpus
--localalloc
--preferred=node
簡單來說,可以指定內存在本地分配,在某幾個CPU 節點分配或輪詢分配。除非設置為 --interleave=nodes
輪詢分配方式,即內存可以在任意NUMA節點上分配這種方式以外其他的方式就算其他 NUMA 節點上還有內存剩余,Linux 也不會把剩余的內存分配給這個進程,而是采用 Swap 的方式獲得內存。所以說:最簡單的方式:關閉這個特性。
關閉特性的方法,分別為:BIOS 關閉 、 操作系統關閉
在操作系統中關閉,可以通過修改 /etc/grub.cfg 在 kernel 行最后添加 numa=off
另外可以設置 vm.zone_reclaim_mode 為 0 盡量回收內存。
還有一個參數 vm.swappiness
是操作系統控制物理內存交換出去的策略。它允許的值是一個百分比的值,最小為0,最大運行100,該值默認為60。vm.swappiness設置為0表示盡量少swap,100表示盡量將inactive的內存頁交換出去。
具體的說:當內存基本用滿的時候,系統會根據這個參數來判斷是把內存中很少用到的inactive 內存交換出去,還是釋放數據的cache。cache中緩存着從磁盤讀出來的數據,根據程序的局部性原理,這些數據有可能在接下來又要被讀 取;inactive 內存顧名思義,就是那些被應用程序映射着,但是 長時間 不用的內存。
Linux中,內存可能處於三種狀態:free,active和inactive。系統內核會根據內存頁的訪問情況,不定時的將活躍active內存被移到inactive列表中,這些inactive的內存可以被 交換到swap中去。
為了盡可能少的交換到 Swap中,最好將 vm.swappiness
設置為 10 或者 1