Redis 已是你們耳熟能詳的東西了,平常工做也都在使用,面試中也是高頻的會涉及到,那麼咱們對它究竟瞭解有多深入呢?面試
我讀了幾本 Redis 相關的書籍,嘗試去了解它的具體實現,將一些底層的數據結構及實現原理記錄下來。後端
本文將介紹 Redis 中底層的 listpack(緊湊列表) 的實現方法。 它是 Redis 的 Stream 用到的數據結構之一。數組
Redis 設計 listpack 的目的就是取代 ziplist, 在 Redis 系列(三)底層數據結構之壓縮列表 中咱們提到,ziplist 在極小的機率下有可能發生級聯更新,當連續規模較大的級聯更新發生時,對 Redis 的性能有比較大的影響。微信
雖然咱們都知道這是極小的機率,可是這種設計缺陷卻不能被 Redis 的大佬做者所接受,所以在 5.0 版本中新引入了一個數據結構,名叫 listpack, 你們都將它翻譯爲 緊湊列表.數據結構
它的定義和 ziplist 極其類似,只是經過一些新的設計,來解決 ziplist 中的痛點問題。所以本文的講解基於讀者已經瞭解 ziplist.性能
ziplist的定義以下: 注意:這是 ziplist 的定義學習
struct ziplist<T>{
// 整個壓縮列表佔用字節數
int32 zlbytes;
// 最後一個節點到壓縮列表起始位置的偏移量,能夠用來快速的定位到壓縮列表中的最後一個元素
int32 zltail_offset;
// 壓縮列表包含的元素個數
int16 zllength;
// 元素內容列表,用數組存儲,內存上緊挨着
T[] entries;
// 壓縮列表的結束標誌位,值永遠爲 0xFF.
int8 zlend;
}
複製代碼
listpack 的定義和上方基本一致,只是去掉了 zltail_offset 屬性。url
讓咱們回想一下,ziplist 中用這個屬性作什麼?用來方便的找到最後一個節點,而後方便進行反向的遍歷。新的 listpack 固然是解決了這個問題,才能放心的刪除掉這個屬性。spa
listpack節點的定義以下:翻譯
int<var> encoding;
optional byte[] content;
int<var> length;
複製代碼
相比於 ziplist 的定義,它有兩點改動:
這樣作的好處是:
listpac 的總長度-最後一個節點的長度
.listpack 是 Redis 設計用來取代掉 ziplist 的數據結構,它經過每一個節點記錄本身的長度,且放在節點的尾部,來完全解決掉了 ziplist 存在的級聯更新的問題。
listpack 在 5.0 版本引入,可是因爲 ziplist 在 Reids 內部的使用太過於普遍,有一些兼容問題,咱們能夠預見這將是一個逐步的替換過程。
一樣在 5.0 版本引入的 Stream 數據結構中,就使用了 listpack 而不是 ziplist.
《Redis 的設計與實現(第二版)》
《Redis 深度歷險:核心原理和應用實踐》
完。
最後,歡迎關注個人我的公衆號【 呼延十 】,會不按期更新不少後端工程師的學習筆記。 也歡迎直接公衆號私信或者郵箱聯繫我,必定知無不言,言無不盡。
以上皆爲我的所思所得,若有錯誤歡迎評論區指正。
歡迎轉載,煩請署名並保留原文連接。
聯繫郵箱:huyanshi2580@gmail.com
更多學習筆記見我的博客或關注微信公衆號 < 呼延十 >------>呼延十