1. 程式人生 > >NUMA導致的MySQL伺服器SWAP問題分析與解決方案

NUMA導致的MySQL伺服器SWAP問題分析與解決方案

【SWAP產生原理】

先從swap產生的原理來分析,由於linux記憶體管理比較複雜,下面以問答的方式列了一些重要的點,方便大家理解:

 1、swap是如何產生的

swap指的是一個交換分割槽或檔案,主要是在記憶體使用存在壓力時,觸發記憶體回收,這時可能會將部分記憶體的資料交換到swap空間。

 2、記憶體回收的機制

<1>Linux核心使用cache對部分檔案進行快取,提升檔案讀寫效率。所以 引入了kswapd程序進行週期性檢查,保證剩餘記憶體空間。

<2>當記憶體分配沒有足夠的空間時,直接記憶體回收。

 3、記憶體回收如何實現

這部分實現非常複雜,簡單來說,記憶體回收操作主要針對記憶體的檔案頁和匿名頁,這些頁都通過LRU連結串列來管理。

其中anon的匿名頁記憶體主要回收手段是swap,檔案頁釋放方式是寫回和清空。

4、講幾個重要的概念

<1>記憶體節點node,在NUMA的情況下,CPU訪問不同位置的記憶體,會有本地記憶體和遠端記憶體之分,這兩個就是不同的節點。

<2>記憶體分割槽 zone,linux對記憶體節點做了進一步劃分,將一個節點劃分為不同的區。記憶體管理的邏輯以zone為單位。

<3>記憶體水位標記,分為high、low、min

通過下圖可以比較直觀的瞭解

5、記憶體回收行為

<1>當系統剩餘記憶體低於low時,kswapd開始起作用進行記憶體回收,直到記憶體達到high水位。

<2>當剩餘記憶體達到min時就會觸發直接回收。

<3>當觸發全域性回收,並且file+free<=high時,一定會進行鍼對匿名頁的swap。

下面舉例:

在資料庫做全備份時cache大量使用,剩餘可用空間不足,觸發記憶體回收,

 

上圖是/proc/zoneinfo的部分內容,可以看到滿足了file+free<=high的條件,同一時間觸發了swap,將記憶體匿名頁的資料寫入交換區

 

有大量的檔案頁cache,為什麼會出現file+free<=high的情況,分析下來全備檔案快取時,node 0的nr_inactive_file很低,大部分非活動的檔案頁都分佈在node 1上,是由於開啟NUMA導致的。

【關閉NUMA的方案】

1、 在mysqld_safe指令碼中加上“numactl –interleave all”來啟動mysqld

2、 Linux Kernel啟動引數中加上numa=off,需要重啟伺服器

3、 在BIOS層面關閉NUMA

4、 MySQL 5.6.27/5.7.9開始引用innodb_numa_interleave選項

對於2、3、4關閉NUMA的方案比較簡單,不做詳細描述,下面重點描述下1方案

【開啟numa interleave訪問的步驟】

1、 yum install numactl -y

2、修改/usr/bin/mysqld_safe檔案

cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"下新增一條指令碼

cmd="/usr/bin/numactl --interleave all $cmd"

3、service mysql stop

4、#寫入硬碟,防止資料丟失

sync;sync;sync

5、#延遲10秒

sleep 10

6、#清理pagecache、dentries和inodes

sysctl -q -w vm.drop_caches=3

7、service mysql start

8、驗證numactl –interleave all是否生效,可以通過下面命令,interleave_hit是採用interleave策略從該節點分配的次數,沒有啟動interleave策略的伺服器,這個值會很低

numastat -mn -p `pidof mysqld`