redis 記憶體碎片引發故障

語言: CN / TW / HK

一.需背景:

某天發現數據有丟失情況,同時redis 日誌斷斷續續有錯誤提示:Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis 

redis 伺服器配置(4核+8G記憶體),資料佔用記憶體240MB ,因開啟rdb+aof 持久化,初步懷疑是aof持久化造成,然後一系列排查(bigkey檢查,記憶體使用情況).最終定位是記憶體碎片佔用太大造成.

 

1.檢視大key:redis-cli -p 6383  -a 'y78231' -n 0 --bigkeys

  

 

2.檢視redis info 記憶體使用情況(忘記截圖大概記得當時伺服器記憶體使用情況)
從info 可見記憶體碎片佔用很大,使用memory purge 命令清理過記憶體碎片,效果微乎其微.

# Memory
used_memory_human:240M
used_memory_rss_human:6.5G
used_memory_peak_human:7.8G
used_memory_peak_perc:97.34%
mem_fragmentation_ratio:24.50
mem_fragmentation_bytes:6577538872 
mem_allocator:libc

 

3.解決

由於之前redis 記憶體分配器是libc,在開啟自動清理記憶體碎片時提示需要安裝Jemalloc 記憶體分配器

jemalloc
Redis在編譯時便會指定記憶體分配器;記憶體分配器可以是 libc 、jemalloc或者tcmalloc,預設是jemalloc。
​jemalloc作為Redis的預設記憶體分配器,在減小記憶體碎片方面做的相對比較好。jemalloc在64位系統中,將記憶體空間劃分為小、大、巨大三個範圍;每個範圍內又劃分了許多小的記憶體塊單位;當Redis儲存資料時,會選擇大小最合適的記憶體塊進行儲存

1.報錯提示:
$ CONFIG SET activedefrag yes
(error) ERR Invalid argument 'yes' for CONFIG SET 'activedefrag' - Active defragmentation cannot be enabled: it requires a Redis server compiled with a modified Jemalloc like the one shipped by default with the Redis source distribution


2.進入redis 原始碼,重新編譯
$ make MALLOC=jemalloc && make install


3.修改redis配置檔案開啟自動清理記憶體碎片

$ vim redis.conf

activedefrag yes :記憶體碎片清理開關
active-defrag-cycle-min 25:表示自動清理過程所用 CPU 時間的比例不低於 25%,保證清理能正常開展 
active-defrag-cycle-max 75:表示自動清理過程所用 CPU 時間的比例不高於 75%,一旦超過,就停止清理,從而避免在清理時,大量的記憶體拷貝阻塞 Redis,導致響應延遲升高



4.重啟redis生效(重啟前先做資料備份以免意外事件)
$ redis-cli -p 6383 -a'y78231'  shutdown &&  redis-server redis.conf