這篇文章帶大家一起了解Redis資料結構中的String類型,並聊聊Redis的KV儲存結構,希望對大家有幫助!
Redis常用作分散式KV緩存,許多人只會使用,卻不知道底層卻有著許多不為人知的秘密。 【相關推薦:Redis影片教學】
String作為Redis支援的最基礎的資料類型,首先我們來看看String,他的資料結構和儲存是怎麼樣的。
眾所周知,redis是用c語言進行寫的,而c語言是沒有String類型的,只有char[],並且在初始化的是時候就必須大小指定型別後就不能改變。為了實現動態增加和擴充等功能,如incr指令,append指令,所以redis就自己定義維護了一個SDS(Simple Dynamic String)來實作這些功能。
我們先來看一下redis原始碼中定義的資料結構,這裡有5種類型,目的是為了節省空間。
1、len:取得char[]的長度,需要遍歷數組,len(char[])時間複雜度O(n);
2、alloc :c語言沒有String類型, 只有char[],且char[]必須先分配空間長度,char[]預先分配了長度,資料增長後需要擴充;
3、falgs:總是佔用一個位元組.其中的最低3個bit用來表示header的型別。 header的類型共有5種,在sds.h有常數定義。
4、buf[]:c語言的char數組,用'\0'代表結束,意味著儲存二進位資料不能包含'\0',圖片音訊等用二進位儲存會有問題-這就是為什麼Redis說自己實作的SDS是二進位安全的字串。
1、Redis實作的SDS支援擴容
2、包含長度len,取得長度複雜度O(1 )
3、空間預先分配
4、惰性空間釋放(下面會講)
在redis中,所有的儲存都是以KV鍵值對的形式儲存的,K是字串類型,就是SDS;V 可能是字串、list、hash等(Redis支援的資料結構),V並沒有直接定成具體的類型,而是用redisObject封裝了一層;實際儲存的資料結構是由ptr指標具體指向。
並且,redis為了更好的節省空間,ptr指針也有不同方式的存儲,一方面,當保存的是Long 類型整數時,RedisObject 中的指針就直接賦值為整數數據了,這樣就不用額外的指針再指向整數了,節省了指針的空間開銷。另一方面,當保存的是字串數據,且字串小於等於 44 個位元組時,RedisObject 中的元數據、指標和 SDS 是一塊連續的記憶體區域,這樣就可以避免記憶體碎片。這種佈局方式也被稱為 embstr 編碼方式。當然,當字串大於 44 位元組時,SDS 的資料量就開始變多了,Redis 就不再把 SDS 和 RedisObject 佈局在一起了,而是會給 SDS 分配獨立的空間,並用指標指向 SDS 結構。這種佈局方式稱為 raw 編碼模式。如圖所示
raw 原生SDS 字元長度 縮減到小於44,會逆向變成embstr編碼嗎?
不會;Redis底層編碼,轉變後 不可逆(不會回退)。
redis是常用的快取中間件,我們必須了解清楚他的資料結構和存儲,以便以使用的時候的選擇更加合適的資料結構和內存的預估。
redis記憶體計算位址 http://www.redis.cn/redis_memory/
更多程式相關知識,請造訪:程式設計入門! !
以上是聊聊Redis資料結構中的String類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!