首頁  >  文章  >  資料庫  >  redis資料結構知識圖文詳解

redis資料結構知識圖文詳解

WBOY
WBOY轉載
2022-04-01 13:31:132758瀏覽

這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了關於資料結構的相關問題,包括了字串、清單、雜湊、有序集合等等相關內容,希望對大家有幫助。

redis資料結構知識圖文詳解

推薦學習:Redis學習教學

redis的資料結構:String(字串)、List(列表)、hash (雜湊)、Set(集合)、Shorted Set(有序集合)

#底層資料結構:簡單動態字串、雙向鍊錶、壓縮列表、雜湊表、跳表、整數陣列
redis資料結構知識圖文詳解
1.雜湊表:一個雜湊表其實就是數組,數組中的每一個元素稱為一個雜湊桶。 redis資料結構知識圖文詳解
雜湊衝突和rehash可能會帶來操作阻塞。
redis解決哈希衝突的方法是鍊式哈希,而rehash是增加現有hash桶的數量。
redis資料結構知識圖文詳解
rehash的操作步驟:1.給哈希表分配更大的空間,例如是當前hash表大小的兩倍
2.把哈希表1中的資料重新映射並且拷貝到hash表2上
3.釋放哈希表1的空間
第二步涉及大量資料拷貝操作,如果一次把哈希表1中的資料都遷移完,會造成線程阻塞,無法服務其他請求。為了避免這個問題,redis採用漸進式rehash
redis資料結構知識圖文詳解
整數陣列和雙向鍊錶的複雜度都是O(N)
壓縮列表在表頭有三個資料分別是列表長度、列表尾的偏移量和列表中entry個數
壓縮列表在表尾還有一個元素zlend代表列表結束redis資料結構知識圖文詳解
跳表:有序鍊錶只能逐一查找元素,而跳表在鍊錶的基礎上增加了多層索引,透過索引位置的幾次跳躍來實現資料的快速定位redis資料結構知識圖文詳解
以下五種結構的時間複雜度
redis資料結構知識圖文詳解

##String類型

String類型並不適用於所有場景,它有一個明顯的短板就是它在保存資料時所消耗的記憶體空間較多。因為String類型需要額外記憶體空間記錄資料長度、空間使用等信息,這些資訊也叫做元資料。

當儲存的資料包含字元的時候,string會用簡單動態字串SDS結構體來保存

redis資料結構知識圖文詳解 len是buf已用長度alloc是buf實際分配長度
因為redis資料型別很多,不同的資料型別有相同的元資料要記錄,所以redis會用一個RedisObject結構體來統一記錄這些元資料

redis資料結構知識圖文詳解 當儲存Long型別的時候,RedisObject的指標就直接賦值為整數資料了,這樣就不用額外的指標再指向整數了,節省了指標的空間開銷。
如果保存的字串小於44字節,sds和元資料會被分配到一塊連續的記憶體區域,被稱為embstr編碼
如果保存的字串大於44字節,SDS和元資料會分開存放,被稱為raw編碼

redis資料結構知識圖文詳解
另外redis會使用一個全域hash表保存所有鍵值對,hash表的每一項都是一個dictEntry的結構體,用來指向一個鍵值對,可以看到key value next會使用24字節,但是實際佔用32字節,這是因為jemalloc 在分配內存時,會根據我們申請的字節數N,找一個比N 大,但是最接近N 的2 的冪次數作為分配的空間,這樣可以減少頻繁分配的次數。
redis資料結構知識圖文詳解
用什麼資料結構可以節省記憶體呢?
壓縮列表:zlbytes代表列表長度,zltail代表列表尾偏移量,zllen代表列表中的entry個數,zlend代表列表結束,perv_len代表前一個entry長度,encoding代表編碼方式,len代表自身長度,key是實際儲存的資料。 redis基於壓縮清單實作了list、hash和Sorted Set

redis資料結構知識圖文詳解
如何以集合類型儲存單一值的鍵值對?
在保存單一值的鍵值對的時候,可以採用Hash的二級編碼,就是把單值的數值拆分成兩部分,前一部分作為Hash的key,後一部分作為Hash的value

以图片 ID 1101000060 和图片存储对象 ID 3302000080 为例,我们可以把图片 ID 的前 7 位(1101000)作为 Hash 类型的键,把图片 ID 的最后 3 位(060)和图片存储对象 ID 分别作为 Hash 类型值中的 key 和 value。127.0.0.1:6379> info memory# Memoryused_memory:1039120127.0.0.1:6379> hset 1101000 060 3302000080(integer) 1127.0.0.1:6379> info memory# Memoryused_memory:1039136

Hash型別有兩種底層實作結構:1.壓縮列表2.Hash表
hash列表存在兩個閥值,一旦超過這兩個閥值就會從壓縮列表轉換為Hash表
hash-max-ziplist-entries表示用壓縮列表保存時哈希列表集合中最大元素個數
hash-max-ziplist-value表示用壓縮列表保存時哈希集合單個元素的最大長度

集合統計模式
1.聚合統計
2.排序統計
3.二值狀態統計
4.基數統計

redis的三種擴充資料型別

1.Bitmap:
2.HyperLogLog
3.GEO:
面向LBS應用的GEO資料型別
GEO的底層結構是根據Sorted Set來實現的,Sorted Set可以根據元素的權重排序,支援範圍查詢redis資料結構知識圖文詳解
sorted Set的權重分數是一個浮點數(float類型),而經緯度是兩個數,需要用GeoHash 編碼
GeoHash編碼是透過「二分區間,區間編碼」的方式進行的。
先把經度和緯度換算成編碼的格式,然後再進行交叉
redis資料結構知識圖文詳解
實際上交叉的目的是下圖所示的概念,交叉後實際上就可以定位到二維在空間上的一個方格中,我們使用Sorted Set 範圍查詢得到的相近編碼值,在實際的地理空間上,也是相鄰的方格,例如1110011101和1111011101是空間位置相鄰的
redis資料結構知識圖文詳解
但是會存在編碼相鄰,但是方格實際上不相鄰的情況。所以為了避免這種情況發生我們可以同時查詢給定經緯度周圍4個或8個方格redis資料結構知識圖文詳解

#如何操作GEO類型?
在使用GEO類型時,我們經常使用到的兩個指令分別時GEOADD和GEORADIUS
GEOADD:用來把一組經緯度資訊和相對應的一個ID記錄到GEO類型集合中。
使用方法:假設車輛ID是33,經緯度位置是(116.034579,39.030452),我們可以用一個 GEO 集合保存所有車輛的經緯度,集合 key 是 cars:locations。只需要執行以下指令就可以把ID號碼為33的車輛的目前經緯度位置存入GEO中。

GEOADD cars:locations 116.034579 39.030452 33

GEORADIUS:根據輸入經緯度的位置,查詢以這個經緯度為中心一定範圍內的其他元素

如何自訂資料類型?

redis的基本物件結構包含type、encoding、lru和refcount、*ptr
redis資料結構知識圖文詳解
開發一個名字叫NewTypeObject的資料結構,具體有以下四個步驟redis資料結構知識圖文詳解

#

如何在redis中保存時間序列資料?

1.基於Hash和Sorted Set保存:為什麼要基於兩種資料結構來查詢呢?
Hash類型可以實現單鍵的快速查詢,這就滿足了時間序列單鍵查詢需求redis資料結構知識圖文詳解
但是hash類型有一個短板就是不支援範圍查詢,為了支援時間戳範圍查詢我們需要透過Sorted Set,因為它是根據元素的權重分數來排序的,redis資料結構知識圖文詳解
那我們怎麼保證這兩個運算的原子性呢?
需要透過MULTI和EXEC兩個指令:
MULTI表示開始,收到這個指令redis就會將指令放入到佇列中
EXEC表示結束,收到這個指令就會開始執行佇列中的指令redis資料結構知識圖文詳解
但是如果採用hash和Sorted Set則只支援範圍查詢而不支援聚合計算。如果在客戶端做聚合計算,會導致大量的網路傳輸。所以可以在redis上透過RedisTimeSeries進行聚合計算。

推薦學習:Redis學習教學

以上是redis資料結構知識圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除