摘要:前言在上一章中我們介紹了的一些內(nèi)部原理在這一章中我們再來討論在五種數(shù)據(jù)結構中的基本使用和一些內(nèi)部實現(xiàn)基本介紹的呢相當于中的也是雙向鏈表具有一些和同樣的特征比如插入和刪除一條很快時間復雜度為獲取頭結點和尾節(jié)點也很快時間復雜度也為隨機讀取則相對
前言
在上一章中我們介紹了 String 的一些內(nèi)部原理,在這一章中我們再來討論在五種數(shù)據(jù)結構中 List 的基本使用和一些內(nèi)部實現(xiàn).
基本介紹Redis的List 呢相當于 Java 中的 LinkedList,也是雙向鏈表.具有一些和 LinkedList 同樣的特征,比如插入和刪除一條很快,時間復雜度為 O(1),獲取頭結點和尾節(jié)點也很快,時間復雜度也為 O(1),隨機讀取則相對較慢時間復雜度為 O(n).常用作消息隊列.
當做隊列使用時,遵循先進先出原則:
> rpush books python java golang (integer) 3 > lpop books "python" > lpop books "java"
當做棧使用時,遵循先進后出原則:
> rpush books python java golang (integer) 3 > rpop books "golang" > rpop books "java"
同時還可以通過 get(index)的方法獲取:
> rpush books python java golang (integer) 3 > lindex books 0 "python" > lindex books -1 "golang"
index從 0 開始,可以為負數(shù) -1 代表倒數(shù)第一個元素
內(nèi)部實現(xiàn)上述部分我們把 Redis 中的 List當做 Java 中的 LinkedList 操作,因為有很多相同的部分.但實際上在 Redis 中鏈表的內(nèi)部實現(xiàn)可不是一個簡單的雙向鏈表.在數(shù)據(jù)量較少的時候它的底層存儲結構為一塊連續(xù)內(nèi)存,稱之為ziplist(壓縮列表).當數(shù)據(jù)量較多的時候?qū)兂涉湵淼慕Y構.后來因為鏈表需要 prev 和 next 兩個指針占用內(nèi)存很多,改用 ziplist+鏈表的混合結構,稱之為 quicklist(快速鏈表).在新的版本中 Redis 鏈表統(tǒng)一使用 quicklist來存儲.下面我們就來詳細介紹這種數(shù)據(jù)結構.
ziplist 壓縮列表先來看看 ziplist 的數(shù)據(jù)結構:
struct ziplist{ int32 zlbytes; //壓縮列表占用字節(jié)數(shù) int32 zltail_offset; //最后一個元素距離起始位置的偏移量,用于快速定位到最后一個節(jié)點 int16 zllength; //元素個數(shù) T[] entries; //元素內(nèi)容 int8 zlend; //結束位 0xFF }
如圖所示:
有了 ztail_offset 就可以快速的定位到最后一個節(jié)點,這樣就可以倒序遍歷了.也就是說 ziplist支持雙向遍歷.
下面再來看下 entry 的內(nèi)部實現(xiàn):
struct entry{ int prevlen; //前一個 entry 的長度 int encoding; //元素類型編碼 optional byte[] content; //元素內(nèi)容 }
當 ziplist 倒序遍歷的時候,就是通過這個pervlen定位到前一個元素位置的.
encoding 保存了 content 的編碼類型.
content 則是保存的元素內(nèi)容,它是optional 類型表示是這個字段是可選的.當content 是很小的整數(shù)時,他會內(nèi)聯(lián)到 encoding 字段的尾部.
quicklist 快速列表quicklist 是 ziplist 和鏈表的混合體.下面是 quicklist和 node 的部分數(shù)據(jù)結構:
struct quicklist{ quicklistNode* head; //指向頭結點 quicklistNode* tail; //指向尾節(jié)點 long count; //元素總數(shù) int nodes; //quicklistNode節(jié)點的個數(shù) int compressDepth; //壓縮算法深度 ... }
為了節(jié)約空間 Redis 還會對 ziplist 使用 LZF 算法進行壓縮,可以選擇壓縮深度.我們待會在說.
如上圖所示,quicklist含有兩個 quicklistNode 代表頭結點和尾節(jié)點,其中每個head 和 tail 之間是雙向鏈表.每個quicklistNode指向一個 ziplist.
struct quicklistNode{ quicklistNode* prev; //前一個節(jié)點 quicklistNode* next; //后一個節(jié)點 ziplist* zl; //壓縮列表 int32 size; //ziplist大小 int16 count; //ziplist 中元素數(shù)量 int2 encoding; //編碼形式 存儲 ziplist 還是進行 LZF 壓縮儲存 ... }
在 quicklist 中每個 ziplist 默認大小是 8kb,超出這個字節(jié)就會增加一個 ziplist.這個默認大小是可配置的,由list-max-ziplist-size決定.
上面說到 ziplist 可以使用 LZF 算法壓縮,通過list-compress-depth配置.默認情況下quicklist 的壓縮深度是 0,也就是不壓縮.配置為 1 的話代表從頭/尾開始第 1 個ziplsit 進行壓縮.
下章預告,Redis 數(shù)據(jù)結構之 Hash
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74914.html
摘要:前言本章接著上一節(jié)繼續(xù)介紹的基礎數(shù)據(jù)結構中的字典基本介紹也可以用來存儲用戶信息和不同的是可以對用戶信息的每個字段單獨存儲則需要序列化用戶的所有字段后存儲并且需要以整個字符串的形式獲取用戶而可以只獲取部分數(shù)據(jù)從而節(jié)約網(wǎng)絡流量不過內(nèi)存占用要大于 前言 本章接著上一節(jié)繼續(xù)介紹 Redis 的基礎數(shù)據(jù)結構中的Hash字典. 基本介紹 Hash 也可以用來存儲用戶信息,和 String 不同的是...
摘要:前言本章將介紹中和的基本使用和內(nèi)部原理因為這兩種數(shù)據(jù)結構有很多相似的地方所以把他們放到一章中介紹并且重點介紹內(nèi)部一個很重要的數(shù)據(jù)結構跳躍表基本介紹先來看看中集合很像中鍵值對無序唯一不為空值重復無序是中最特別的基礎數(shù)據(jù)結構其他幾個都能和大致對 前言 本章將介紹 Redis中 set 和 zset的基本使用和內(nèi)部原理.因為這兩種數(shù)據(jù)結構有很多相似的地方所以把他們放到一章中介紹.并且重點介紹...
閱讀 1628·2021-11-22 13:53
閱讀 2868·2021-11-15 18:10
閱讀 2768·2021-09-23 11:21
閱讀 2515·2019-08-30 15:55
閱讀 486·2019-08-30 13:02
閱讀 765·2019-08-29 17:22
閱讀 1709·2019-08-29 13:56
閱讀 3462·2019-08-29 11:31