Redis使用Swap,但系統可用內存充足

最近生產環境遇到一個很奇怪的問題,系統內存32G,redis使用8G左右,剩餘的內存都被系統cache使用,從表面上看系統可用內存有20G左右。可是系統運行過程當中,redis時不時會用到swap,並且在AOF重寫期間swap使用量更是突增(mem_fragmentation_ratio 值低於1)致使redis性能嚴重降低。html

而後搜索網上的各類資料,調整redis參數,主要作了如下幾個部分:redis

一、調整/ proc/sys/vm/swappinessapp

二、調整 no-appendfsync-on-rewrite yes,減小AOF重寫時的IO爭用性能

三、添加最大內存限制 maxmemory 24gbspa

四、手動釋放cache echo 1 > /proc/sys/vm/drop_caches,釋放後系統過一段時間又會佔滿htm

以上操做完成後,仍然沒有效果。blog

而後採起臨時手段,在備機上將swap分區禁用,暫時解決問題,主機仍然保留現場繼續查問題(這期間調整auto-aof-rewrite-percentage 300,減小重寫頻率)。進程

最後查看到關於NUMA的資料,結合生成環境系統分析,確認存在內存分配策略問題的這種可能性。內存

大概的緣由以下:資源

在多核CPU的環境下,numa採用對CPU和內存分組的方式管理資源,每一個CPU分組對應1個內存分組,在默認策略狀況下,CPU使用本身組內的內存空間,若新進程申請內存時,沒有足夠的空閒內存,則可能用到swap空間,而不去其餘CPU組申請內存。

這裏有一個簡單的驗證方法:

一、手工釋放cache echo 1 > /proc/sys/vm/drop_caches

二、numactl --hardware  查看每一個CPU分組中空餘內存大小是否基本一致,若出現某個組free很小,其餘組明顯大於該組,則多是內存策略分配引發的問題。

注意:這裏看到的free是不含cache部分佔用的內存,因此要先釋放一下cache

解決辦法:

在redis啓動命令前面加上 numactl --interleave=all ,表示採用輪詢的方式到各組申請內存,這樣重啓redis後問題解決,改善的點以下:

一、redis AOF重寫時再也不使用到swap,重寫基本在1分鐘左右完成(故障期間長達30分鐘)

二、sar -b 查看IO,每秒寫入量和tps均有明細降低

三、redis內存碎片指數 mem_fragmentation_ratio 一直保持大於1

NUMA參考資料http://www.cnblogs.com/xueqiuqiu/articles/9282903.html

相關文章
相關標籤/搜索