Redis拓展知識
一、消息
1.sub/pub

- 實現(xiàn)了一個建議的消息隊列,實現(xiàn)了發(fā)布者與訂閱者的模式,生產(chǎn)者和消費者是不同的連接;
- 如果一個消費者沒有消息會直接舍棄,消息沒有ack機制,且消息不持久化。
2.Stream

- redis5.0提出了支持多播的可持久化的消息隊列Stream,參照了kafka分組的設計(stream沒有分區(qū)的概念,分區(qū)需要在客戶端完成);
- 每個Stream可以掛多個消費者組,其中有一個游標標識消費到了哪條消息,一個消費者組中的消費者是競爭的關系,消費者內(nèi)部由一個pending_id(PEL,Pending Entries List)記錄沒有ack的消息;
- 操作指令:xadd、xdel、xrange、xlen、del;
- 消費分為兩個類型,可以單個消費者xread消費,也可以消費者組xreadgroup消費,可以阻塞,可以不阻塞消費;
- stream消息鏈表xdel不會刪除消息只是做一個標識,消息鏈表的定長長度maxlen會限制消息的長度;
二、過期策略
- 刪除策略:設置過期的key單獨放在一個獨立的字典,會采用定期掃描的集中處理和懶惰刪除的零散處理,主從結構從節(jié)點刪除依賴于主節(jié)點的aof日志。
- 刪除原理:默認每秒進行10次過期掃描,采用貪心策略,先隨機20個key進行過期刪除,如果過期的超過1/4再繼續(xù)選取,默認的掃描時間不會超過25ms。為了避免一個時間同一時間過期時間key過多導致客戶端超時斷開連接失敗,設置超時時間盡量不要在同一時間過期;
- 懶惰刪除:del刪除大key、unlink指令、flushdb async、flushall async都可以進行異步的刪除,原理事放在一個異步的任務隊列(雙向鏈表)中慢慢的刪除。
三、內(nèi)存更新LRU
- 刪除策略:當實際內(nèi)存超過maxmemory時,有以下幾種可算的策略。
- noeviction:(默認)不會繼續(xù)服務寫請求(不包括del),讀請求可以繼續(xù);
- volatile-lru:嘗試淘汰設置了過去時間的key,最少使用的key優(yōu)先被淘汰;
- volatile-ttl:嘗試淘汰設置了過去時間的key,剩余ttl壽命越小優(yōu)先淘汰;
- volatile-random:嘗試淘汰設置了過去時間的key,剩余ttl壽命越小優(yōu)先淘汰;
- volatile-random:嘗試淘汰設置了過去時間的key,隨機淘汰;
- allkeys-lru:全體key最少使用的key優(yōu)先被淘汰;
- allkeys-random:全體key隨機淘汰;
2.LRU算法:
- 傳統(tǒng)LRU算法,鏈表結構,按照一定的順序排列,被訪問了就放在鏈表的頭部,淘汰時淘汰鏈表的尾端;
- redis的LRU算法,傳統(tǒng)LRU算法需要消耗額外的內(nèi)存,在現(xiàn)有基礎上采用隨機采樣法,給每個key加一個字段,長度24bit,表示最后使用的時間戳;
- 采用懶惰算法:執(zhí)行寫的操作時候發(fā)現(xiàn)超內(nèi)存,隨機采樣出5個(maxmemory_samples可設置)淘汰,如果淘汰后內(nèi)存還不足,繼續(xù)淘汰;
3.LFU算法:
Redis4.0后按最近的訪問頻率進行淘汰,防止一個key偶爾被訪問一次被當作熱key;
-
數(shù)據(jù)結構:
last decrement time 16bit logistic counter 8 bit ① logc存儲訪問頻率,頻次的對數(shù),該值會隨著時間衰減,初始化key默認是5,每訪問一次就更新,采用概率法遞增;
② ldt存儲上次logc更新的時間,2的16次方取模,精度是分鐘,在淘汰時才更新,更新時會衰減logc([當前值-對象空現(xiàn)時間]/衰減系數(shù)[默認1])的值;