為了解決redis使用del命令刪除大體積的key,或者使用flushdb、flushall刪除數據庫時,造成redis阻塞的情況,在redis 4.0引入了lazyfree機制,可將刪除操作放在后台,讓后台子線程(bio)執行,避免主線程阻塞。
lazy free的使用分為2類:第一類是與DEL命令對應的主動刪除,第二類是過期key刪除、maxmemory key驅逐淘汰刪除。
主動刪除
UNLINK命令是與DEL一樣刪除key功能的lazy free實現。唯一不同時,UNLINK在刪除集合類鍵時,如果集合鍵的元素個數大於64個(詳細后文),會把真正的內存釋放操作,給單獨的bio來操作。
127.0.0.1:7000> UNLINK mylist (integer) 1 FLUSHALL/FLUSHDB ASYNC 127.0.0.1:7000> flushall async //異步清理實例數據
被動刪除
lazy free應用於被動刪除中,目前有4種場景,每種場景對應一個配置參數; 默認都是關閉。
lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no slave-lazy-flush no
lazyfree-lazy-eviction
針對redis內存使用達到maxmeory,並設置有淘汰策略時;在被動淘汰鍵時,是否采用lazy free機制;
因為此場景開啟lazy free, 可能使用淘汰鍵的內存釋放不及時,導致redis內存超用,超過maxmemory的限制。此場景使用時,請結合業務測試。
lazyfree-lazy-expire
針對設置有TTL的鍵,達到過期后,被redis清理刪除時是否采用lazy free機制;
此場景建議開啟,因TTL本身是自適應調整的速度。
lazyfree-lazy-server-del
針對有些指令在處理已存在的鍵時,會帶有一個隱式的DEL鍵的操作。如rename命令,當目標鍵已存在,redis會先刪除目標鍵,如果這些目標鍵是一個big key,那就會引入阻塞刪除的性能問題。 此參數設置就是解決這類問題,建議可開啟。
slave-lazy-flush
針對slave進行全量數據同步,slave在加載master的RDB文件前,會運行flushall來清理自己的數據場景,
參數設置決定是否采用異常flush機制。如果內存變動不大,建議可開啟。可減少全量同步耗時,從而減少主庫因輸出緩沖區爆漲引起的內存使用增長。
expire及evict優化
redis在空閑時會進入activeExpireCycle循環刪除過期key,每次循環都會率先計算一個執行時間,在循環中並不會遍歷整個數據庫,而是隨機挑選一部分key查看是否到期,所以有時時間不會被耗盡(采取異步刪除時更會加快清理過期key),剩余的時間就可以交給freeMemoryIfNeeded來執行。
摘自:https://zhuanlan.zhihu.com/p/59511903