記憶體碎片大家都已經耳熟能詳了。當Redis資料刪除後,Redis釋放的記憶體空間可能不是連續的,這就會帶來一個問題,這些不連續的記憶體空間有可能處於閒置的,但是redis缺無法來儲存資料,這就會減低Redis儲存的資料量。
那我們該如何來判斷Redis是否存在記憶體碎片呢?
Redis提供了一個Info memory命令,可以用來查詢記憶體使用的詳細資訊。如下所示。
127.0.0.1:6379> info memory
# Memory
used_memory:1074976
used_memory_human:1.03M
used_memory_rss:1548288
used_memory_rss_human:1.48M
used_memory_peak:1075888
used_memory_peak_human:1.03M
used_memory_peak_perc:99.92%
used_memory_overhead:1071226
used_memory_startup:987328
used_memory_dataset:3750
used_memory_dataset_perc:4.28%
allocator_allocated:1041632
allocator_active:1502208
allocator_resident:1502208
total_system_memory:17179869184
total_system_memory_human:16.00G
used_memory_lua:46080
used_memory_lua_human:45.00K
used_memory_scripts:216
used_memory_scripts_human:216B
number_of_cached_scripts:1
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.44
allocator_frag_bytes:460576
allocator_rss_ratio:1.00
allocator_rss_bytes:0
rss_overhead_ratio:1.03
rss_overhead_bytes:46080
mem_fragmentation_ratio:1.49
mem_fragmentation_bytes:506656
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:83538
mem_aof_buffer:0
mem_allocator:libc
active_defrag_running:0
lazyfree_pending_objects:0
複製程式碼
注意,這裡有一個mem_fragmentation_ratio的指標,這個就代表了Redis的記憶體碎片率,它的計算方式是used_memory_rss 和 used_memory 相除。
- used_memory_rss 是作業系統實際分配給Redis的實體記憶體空間,裡面就包含了碎片;
- used_memory 是Redis為了儲存資料實際申請使用的空間。
當我們發現mem_fragmentation_ratio這個指標大於1.5,這就表明記憶體的碎片碎片使用率超過了50%,我們就需要來採取措施減低記憶體碎片率了。
如何清理記憶體碎片
最簡單粗暴的方式就是重啟redis,但是這對於線上服務來說是不友好的,那有沒有更好的辦法呢,自從Redis 4.0-RC3版本開始,Redis自身提供了一種記憶體碎片自動清理方法,當redis需要啟用自動記憶體碎片清理,可以把activedefrag設定為yes。這個命令只是啟動了了自動清理功能。具體怎麼清理有下面兩個引數的配置來控制。如果同時滿足這兩個條件,就開始清理,如果有一個不滿足,就停止清理。
- active-defrag-ignore-bytes 120mb 表示記憶體碎片的位元組數達到120MB時,開始清理;
- active-defrag-threshold-lower 15% 表示記憶體碎片空間佔作業系統分配給Redis的總空間比例達到15%時,開始清理。
Redis為了減低記憶體碎片清理對正常請求的影響,在自動記憶體碎片清理執行過程中,會監控清理操作佔用CPU的時間,有兩個引數分別用於控制清理操作佔用CPU時間的上下限。
active-defrag-cycle-min 30: 表示自動清理過程所用CPU時間的比例不低於30%,保證清理能正常開展;
active-defrag-cycle-max 70: 表示自動清理過程所用 CPU 時間的比例不高於 70%,一旦超過,就停止清理,從而避免在清理時,影響redis的正常操作。
今天我們關於Redis的記憶體碎片就聊到這。更多硬核知識,請關注公眾號【程式設計師學長】。