Redis不同數據類型的的數據結構實現


我們知道Redis支持五種數據類型,

分別是字符串、哈希表(map)、列表(list)、集合(set)和有序集合,和Java的集合框架類似,不同數據類型的數據結構實也是不一樣的。

1.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)

下面針對五種數據類型,學習相關的底層數據結構。

2.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 1
OK
redis:6379> OBJECT ENCODING strtest
"int"
redis:6379> set strtest blog
OK
redis:6379> OBJECT ENCODING strtest
"raw"

  

3.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內容較多時,使用雙向鏈表。

4.Hash

創建新的Hash類型時,默認也使用ziplist存儲value,保存數據過多時,使用hast table。

5.Set

集合的底層實現也有兩種:
REDIS_ENCODING_INTSET
REDIS_ENCODING_HT(字典)
創建Set類型的key-value時,如果value能夠表示為整數,則使用intset類型保存value。
數據量大時,切換為使用hash table保存各個value。

6.Sorted Set

有序集合的底層實現也是2種:
REDIS_ENCODING_ZIPLIST
REDIS_ENCODING_SKIPLIST

關於Redis中的跳躍表,查看這篇文章:跳躍表
跳躍表在 Redis中的使用,就是實現有序集合數據類型。

 

應用版本Redis 2.6,

了解更多:Redis 數據類型

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM