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

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

接下來咱們要剖析的基本類型是List,相信你們對List都不會陌生吧,下面咱們將深刻源碼剖析Redis中List的實現。node

存儲類型redis

存儲有序的字符串(從左到右),元素能夠重複。能夠充當隊列和棧的角色。算法

操做命令測試

元素增減ui

lpush queue a
lpush queue b c
rpush queue d e
lpop queue
rpop queue
​blpop queue
brpop queue

取值spa

lindex queue 0
lrange queue 0 -1

存儲( 實現) 原理code

在早期的版本中,數據量較小時用 ziplist 存儲,達到臨界值時轉換爲linkedlist 進行存儲,分別對應 OBJ_ENCODING_ZIPLIST 和OBJ_ENCODING_LINKEDLIST 。blog

3.2 版本以後,統一用 quicklist 來存儲。quicklist 存儲了一個雙向鏈表,每一個節點都是一個 ziplist。隊列

127.0.0.1:6379> object encoding queue
"quicklist"
什麼是quicklist?

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

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資源免費等你來拿!!!``

                         

相關文章
相關標籤/搜索