Redis外部數據結構與內部數據結構

外部數據結構與內部數據結構

外部數據結構除了常用的5種:字符串String,哈希表Hash,列表List,集合Set,有序集合Sort Set,還有數據結構bitmapHyperLogLogGeo,Streams。外部結構對外使用,根據數據類型的不同,Redis內選用不同的內部結構。

Redis數據結構

這樣設計的好處是改變內部編碼對外部沒有影響(包裝者模式),外部的數據結構和命令無需改變,多種內部數據結構可以發揮各自的優勢。

外部數據、內部數據結構查看指令:

> set name zhangsan
OK
> type name
string
> object encoding name
embstr

1.string

  • int 8個字節的長整型
  • embstr 小于44個字節的字符串
  • raw 大于44個字節小于512M的字符串
int

當value是整型時,內部就會使用int。

embstr與raw

embstr編碼將創建字符串對象所需的空間分配的次數從raw編碼的兩次降低為一次。因為embstr編碼的字符串對象的所有數據都保存在一塊連續的內存里面,所以這種編碼的字符串對象比起raw編碼的字符串對象能更好地利用緩存帶來的優勢。并且釋放embstr編碼的字符串對象只需要調用一次內存釋放函數,而釋放raw編碼對象的字符串對象需要調用兩次內存釋放函數。

2.hash

  • 當filed的個數少于512,且沒有value大于64字節時,內部編碼為ziplist
  • 當filed的個數大于512,或者value大于64字節時,內部編碼為hashtable
> hmset rank 1 yuwei 2 yuwei2 3 yuwei3
OK
> object encoding rank
ziplist
> hset rank 4 "Redis modules can access Redis built-in data structures both at high level, by calling Redis commands, and at low level, by manipulating the data structures directly."
1
> object encoding rank
hashtable
ziplist

list、hash、Sort Set三種外部結構,在某些情況下內部數據結構都使用了ziplist,因為ziplist充分體現了Redis對于存儲效率的追求。

一個普通的雙向鏈表,每一個節點都會占用一塊內容,各個節點通過指針連接,這種方式會產生大量的內存碎片,而且地址指針會占用額外的內存空間。ziplist將列表中的每一項存放在一塊連續的地址空間內,所以一個ziplist只占一塊大的內存。

hashtable

和Java中的HashMap一樣。

3.list

  • 3.2之前

    • 當列表list中的元素個數少于512,且沒有value大于64字節時,內部編碼為ziplist
    • 當列表list中的元素個數大于512,或者value大于64字節時,內部編碼為linkedlist
  • 3.2 之后

    都使用quicklist

    > rpush ques 123 234
    2
    > object encoding ques
    quicklist
    
linkedlist

雙向鏈表,沒啥說的。

quicklist

quicklist結合了雙向列表linkedlist和ziplist的特點,它是一個雙向無環鏈表,它的每一個節點都是一個ziplist,所有的節點都用quicklist存儲,省去了臨界時的格式轉換。

4.set

  • 當集合set中的元素都是整數且元素個數小于512(默認時)使用intset
  • 其它條件使用hashtable
> sadd ques 1 2 3
3
> object encoding ques
intset
> sadd ques aaa
1
> object encoding ques
hashtable
intset

Set特殊內部編碼,它是一個有序的整形數組,再內存分配上和ziplist有些類似,是連續的一塊內存空間。

5.Sort Set

  • 元素個數少于128(默認為128),且沒有value大于64字節時,內部編碼為ziplist
  • 元素個數大于128(默認為128),或者value大于64字節時,內部編碼為skiplist
> zadd ques 1 zhangsan 2 lisi
2
> object encoding ques
ziplist
> zadd ques 3 "Redis modules can access Redis built-in data structures both at high level, by calling Redis commands, and at low level, by manipulating the data structures directly."
1
> object encoding ques
skiplist
skiplist

跳表skiplist

Sorted set實現多維排序

Sorted set默認只使用一個因子進行排序,如果想要實現根據多個因子進行排序,比如外賣綜合排序需要考慮距離,評分,價格,就需要將多個排序因子轉換為一個排序因子,result = function(x, y, z)。

6.bitmap

bitmap實現了Redis的Bloom Filter(布隆過濾器)。

bitmap并不是一個真實的數據機構,它本質是String數據結構,不過操作的粒度是bit。String最大的長度是512M,所以bitmap允許存儲2^32個bit。

bloomFilter

Bloom Filter用于判斷一個元素是否存在于集合中,他的空間效率和時間效率遠超過一般的算法,不過會有一定的誤識別率(3%)。

當一個元素被加入集合時,通過K個散列函數將這個元素映射成一個位數組中的K個點,把它們置為1。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:如果這些點有任何一個0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。

Bloom Filter跟單哈希函數Bit-Map不同之處在于:Bloom Filter使用了k個哈希函數,每個字符串跟k個bit對應。從而降低了沖突的概率。

7.Geo

GEO功能在Redis3.2版本提供,使用Geo可以在Redis中存儲地理坐標,用來實現諸如附近位置、搖一搖這類依賴于地理位置信息的功能.

和bitmap一樣,Geo并不是一個數據結構,本質上是Sort Set,并且使用GeoHash技術進行填充。

8.HyperLogLog

HyperLogLog 是用來做基數統計的算法,基數統計的意思是一個集合中不重復元素的個數。即使元素的數量或體積特別大,計算基數所需要的空間是固定的,而且很小。

> PFADD hll a b c d e f g
1
> object encoding hll
raw

9.Streams

Streams是Redis5.0以后引入的數據結構,Streams就是Redis實現的內存版kafka。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。