1. 程式人生 > 程式設計 >深入學習Redis(四),基本型別【List】剖析

深入學習Redis(四),基本型別【List】剖析

更多精彩文章,關注【ToBeTopJavaer】,更有數萬元精品vip資源免費等你來拿!!!

接下來我們要剖析的基本型別是List,相信大家對List都不會陌生吧,下面我們將深入原始碼剖析Redis中List的實現。

儲存型別


儲存有序的字串(從左到右),元素可以重複。可以充當佇列和棧的角色。 操作命令


元素增減
lpush queue a
lpush queue b c
rpush queue d e
lpop queue
rpop queue
​blpop queue
brpop queue複製程式碼
取值
lindex queue 0
lrange queue 0 -1複製程式碼
儲存( 實現) 原理


在早期的版本中,資料量較小時用 ziplist 儲存,達到臨界值時轉換為 linkedlist 進 行儲存,分別對應 OBJ_ENCODING_ZIPLIST 和 OBJ_ENCODING_LINKEDLIST 。 3.2 版本之後,統一用 quicklist 來儲存。quicklist 儲存了一個雙向連結串列,每個節點 都是一個 ziplist
127.0.0.1:6379> object encoding queue
"quicklist"複製程式碼
什麼是quicklist?

quicklist(快速列表)是 ziplist 和 linkedlist 的結合體。

quicklist.h原始碼如下,head 和 tail 指向雙向列表的表頭和表尾
typedef struct quicklist {
  quicklistNode *head; /* 指向雙向列表的表頭 */
  quicklistNode *tail; /* 指向雙向列表的表尾 */
  unsigned long count; /* 所有的 ziplist 中一共存了多少個元素 */
  unsigned long len; /* 雙向連結串列的長度, node 的數量 */
  int fill : 16; /* fill factor for individual nodes */
  unsigned int compress : 16; /* 壓縮深度, 0: 不壓縮; */
} quicklist;複製程式碼
redis.conf 相關引數:
list-max-ziplist-size(fill)
正數表示單個 ziplist 最多所包含的 entry 個數。
負數代表單個 ziplist 的大小, 預設 8k。 -1: 4KB; -2: 8KB; -3: 16KB; -4: 32KB; -5: 64KB


list-compress-depth(compress)
壓縮深度, 預設是 0。 其它值含義: 1: 首尾的 ziplist 不壓縮; 2: 首尾第一第二個 ziplist 不壓縮, 以此類推 quicklistNode 中的*zl 指向一個 ziplist,一個 ziplist 可以存放多個元素。

原始碼如下:

typedef struct quicklistNode {
  struct quicklistNode *prev; /* 前一個節點 */
  struct quicklistNode *next; /* 後一個節點 */
  unsigned char *zl; /* 指向實際的 ziplist */
  unsigned int sz; /* 當前 ziplist 佔用多少位元組 */
  unsigned int count : 16; /* 當前 ziplist 中儲存了多少個元素, 佔 16bit(下同) , 最大 65536 個 */
  unsigned int encoding : 2; /* 是否採用了 LZF 壓縮演演算法壓縮節點, 1: RAW 2: LZF */
  unsigned int container : 2; /* 2: ziplist, 未來可能支援其他結構儲存 */
  unsigned int recompress : 1; /* 當前 ziplist 是不是已經被解壓出來作臨時使用 */
  unsigned int attempted_compress : 1; /* 測試用 */
  unsigned int extra : 10; /* 預留給未來使用 */
} quicklistNode;複製程式碼

原始碼結構圖



ziplist 的結構在探討Hash時已經說過了,不再重複。


應用場景


使用者訊息時間線 timeline
因為 List 是有序的,可以用來做使用者時間線 訊息佇列


List 提供了兩個阻塞的彈出操作:BLPOP/BRPOP,可以設定超時時間。


BLPOP:BLPOP key1 timeout 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。

BRPOP:BRPOP key1 timeout 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。


佇列:先進先出:rpush blpop,左頭右尾,右邊進入佇列,左邊出佇列。


棧:先進後出:rpush brpop


今天我們從底層原始碼剖析了基本資料型別List,接下來我們將會對剩下的幾個常用的基本型別的深入探討,敬請期待。
更多精彩文章,關注【ToBeTopJavaer】,更有數萬元精品vip資源免費等你來拿!!!