redisobject詳解

前面說到,Redis對象有5種類型;無論是哪種類型,Redis都不會直接存儲,
而是通過redisObject對象進行存儲。
  • redisObject對象非常重要,Redis對象的類型、內部編碼、內存回收、共享對象等功能,都需要redisObject支持,下面將通過redisObject的結構來說明它是如何起作用的。
  • redisObject的定義如下(列出了與保存數據有關的三個屬性):
typedef struct redisObject 
{ 
	unsigned type:4; 
	unsigned encoding:4; 
	unsigned lru:REDIS_LRU_BITS;  
	/* lru time (relative to server.lruclock) */  
	int refcount; 
	void *ptr;
} robj;

redisObject的每個字段的含義和作用如下:
(1)type
type字段表示對象的類型,佔4個比特;目前包括REDIS_STRING(字符串)、REDIS_LIST (列表)、REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有序集合)。
當我們執行type命令時,便是通過讀取RedisObject的type字段獲得對象的類型;如下圖所示:
在這裏插入圖片描述

(2)encoding

  • encoding表示對象的內部編碼,佔4個比特。
    對於redis支持的每種類型都至少有兩種編碼,對於字符串有int、embsre、row三種
    通過encoding屬性,redis可以根據不同的使用場景來對對象使用不同的編碼,大大提高的redis的靈活性和效率。
    在這裏插入圖片描述
  • 以列表對象爲例,有壓縮列表和雙端鏈表兩種編碼方式;如果列表中的元素較少,
    Redis傾向於使用壓縮列表進行存儲,因爲壓縮列表佔用內存更少,而且比雙端鏈表可以更快載入;當列表對象元素較多時,壓縮列表就會轉化爲更適合存儲大量元素的雙端鏈表。3.2版本以後都採用quicklist, 是壓縮鏈表和雙端鏈表的結合。
  • 什麼意思呢,比如,一個包含三個結點的quicklist,如果每個結點的ziplist又包含四個數據項,那麼對外表現上,這個list就總共包含12個數據項。這樣的設計,實際上是對於時間和空間的一種折中
  • linkedlist便於在表的兩端進行push和pop操作,但是它的內存開銷較大。首先,它的每個節點除了要保存數據之外還要額外保存兩個指針;其次,雙向鏈表的各個節點是單獨的內存塊,地址不連續,容易產生內存碎片,還容易造成抖動。
    ziplist由於是一整塊連續的內存,存儲效率很高,但不利於添加和刪除操作,每次都會重新realloc,尤其是當ziplist很長的時候,一次realloc造成的開銷特別的大,查詢的開銷也特別的大。

在這裏插入圖片描述

列表、hash、集合、有序結合的內部編碼實例圖:
在這裏插入圖片描述

這裏來一個redisObject的全類型圖:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章