標籤:
我們知道Redis支援五種資料類型,
分別是字串、雜湊表(map)、列表(list)、集合(set)和有序集合,和Java的集合架構類似,不同資料類型的資料結構實也是不一樣的。
>>Redis中的redisObject對象
Redis是使用C編寫的,內部實現了一個struct結構體redisObject對象,
通過結構體來模仿物件導向編程的“多態”,作為一個底層的資料支援,redisObject代碼:
/* * Redis 對象 */typedef struct redisObject { // 類型 unsigned type:4; // 對齊位 unsigned notused:2; // 編碼方式 unsigned encoding:4; // LRU 時間(相對於 server.lruclock) unsigned lru:22; // 引用計數 int refcount; // 指向對象的值 void *ptr;} robj;
其中type、encoding、ptr3個屬性分別表示:
type:redisObject的類型,字串、列表、集合、有序集、雜湊表
encoding:底層實現結構,字串、整數、跳躍表、壓縮列表等
ptr:實際指向儲存值的資料結構
如果一個 redisObject 的 type 屬性為 REDIS_LIST , encoding 屬性為 REDIS_ENCODING_LINKEDLIST ,
那麼這個對象就是一個 Redis 列表,它的值儲存在一個雙端鏈表內,而 ptr 指標就指向這個雙端鏈表;
如果一個 redisObject 的 type 屬性為 REDIS_HASH , encoding 屬性為 REDIS_ENCODING_ZIPMAP ,
那麼這個對象就是一個 Redis 雜湊表,它的值儲存在一個 zipmap 裡,而 ptr 指標就指向這個 zipmap 。
下面這張圖片中的REDIS_STRING/REDIS_LIST/REDIS_ZSET/REDIS_HASH/REDIS_SET針對的是redisObject中的type,
後面指向的REDIS_ENCODING_LINKEDLIST等針對的是encoding欄位。
Redis的底層資料結構有以下幾種:
簡單動態字串sds(Simple Dynamic String)
雙端鏈表(LinkedList)
字典(Map)
跳躍表(SkipList)
下面針對五種資料類型,學習相關的底層資料結構。
>>String
如果一個String類型的value能夠儲存為整數,則將對應redisObject 對象的encoding修改為REDIS_ENCODING_INT,將對應robj對象的ptr值改為對應的數值。
如果不能轉為整數,保持原有encoding為REDIS_ENCODING_RAW。
因此String類型的資料可能使用原始的字串儲存(實際為sds - Simple Dynamic Strings,對應encoding為REDIS_ENCODING_RAW)或者整數儲存。
Redis可以直接查看對象的ENCODING值:
redis:6379> set strtest 1OKredis:6379> OBJECT ENCODING strtest"int"redis:6379> set strtest blogOKredis:6379> OBJECT ENCODING strtest"raw"
>>List
列表的底層實現有2種:
REDIS_ENCODING_ZIPLIST
REDIS_ENCODING_LINKEDLIST
ZIPLIST相比LINKEDLIST可以節省記憶體,
當建立新的列表時,預設是使用壓縮列表作為底層資料結構的。
Redis內部會對相關操作做判斷,
當list的elem數小於配置值: hash-max-ziplist-entries 或者elem_value字串的長度小於 hash-max-ziplist-value, 可以編碼成 REDIS_ENCODING_ZIPLIST 類型儲存,以節約記憶體;
但由於在zip list添加和刪除元素會涉及到資料移動,
因此當list內容較多時,使用雙向鏈表。
>>Hash
建立新的Hash類型時,預設也使用ziplist儲存value,儲存資料過多時,使用hast table。
>>Set
集合的底層實現也有兩種:
REDIS_ENCODING_INTSET
REDIS_ENCODING_HT(字典)
建立Set類型的key-value時,如果value能夠表示為整數,則使用intset類型儲存value。
資料量大時,切換為使用hash table儲存各個value。
>>Sorted Set
有序集合的底層實現也是2種:
REDIS_ENCODING_ZIPLIST
REDIS_ENCODING_SKIPLIST
關於Redis中的跳躍表,查看這篇文章:跳躍表
跳躍表在 Redis中的使用,就是實現有序集合資料類型。
非一手資料,相關分析整理自論壇部落格等,版本Redis 2.6。
瞭解更多:Redis 資料類型
Redis不同資料類型的的資料結構實現