dict 是主要是由 struct dictht 的 哈唏表構成的, 之所以定義成長度為2的( dictht ht[2] ) 哈唏表數組,是因為 redis 採用漸進的 rehash,即當需要 rehash 時,每次像 hset,hget 等操作前,先執行N 步 rehash. 這樣就把原來一次性的 rehash過程拆散到進行, 防止一次性 rehash 期間 redis 服務能力大幅下降. 這種漸進的 rehash 需要一個額外的 struct dictht 結構來儲存.
struct dictht 主要是由一個 struct dictEntry 指標數組組成的, hash 表的衝突是通過鏈表法來解決的.
struct dictEntry 中的 key 指標指向用 sds 類型表示的 key 字串, val 指標指向一個 struct redisObject 結構體, 其定義如下:
typedef struct redisObject{unsigned type:4;unsigned storage:2; /* REDIS_VM_MEMORY or REDIS_VM_SWAPPING */unsigned encoding:4;unsigned lru:22; /* lru time (relative to server.lruclock) */int refcount;void *ptr;/* VM fields are only allocated if VM is active, otherwise the* object allocation function will just allocate* sizeof(redisObjct) minus sizeof(redisObjectVM), so using* Redis without VM active will not have any overhead. */} robj;//type 占 4 bit,用來表示 key-value 中 value 值的類型,目前 redis 支援: string, list, set,zset,hash 5種類型的值./* Object types */#define REDIS_STRING 0#define REDIS_LIST 1#define REDIS_SET 2#define REDIS_ZSET 3#define REDIS_HASH 4#define REDIS_VMPOINTER 8// storage 占 2 bit ,表示 此值是在 記憶體中,還是 swap 在硬碟上.// encoding 占 4 bit ,表示值的編碼類別型,目前有 8種類型:/* Objects encoding. Some kind of objects like Strings and Hashes can be* internally represented in multiple ways. The 'encoding' field of the object* is set to one of this fields for this object. */#define REDIS_ENCODING_RAW 0 /* Raw representation */#define REDIS_ENCODING_INT 1 /* Encoded as integer */#define REDIS_ENCODING_HT 2 /* Encoded as hash table */#define REDIS_ENCODING_ZIPMAP 3 /* Encoded as zipmap */#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */#define REDIS_ENCODING_INTSET 6 /* Encoded as intset */#define REDIS_ENCODING_SKIPLIST 7 /* Encoded as skiplist *//* 如 type 是 REDIS_STRING 類型的,則其值如果是數字,就可以編碼成 REDIS_ENCODING_INT,以節約記憶體.* 如 type 是 REDIS_HASH 類型的,如果其 entry 小於配置值: hash-max-zipmap-entries 或 value字串的長度小於 hash-max-zipmap-value, 則可以編碼成 REDIS_ENCODING_ZIPMAP 類型儲存,以節約記憶體. 否則採用 Dict 來儲存.* 如 type 是 REDIS_LIST 類型的,如果其 entry 小於配置值: list-max-ziplist-entries 或 value字串的長度小於 list-max-ziplist-value, 則可以編碼成 REDIS_ENCODING_ZIPLIST 類型儲存,以節約記憶體; 否則採用 REDIS_ENCODING_LINKEDLIST 來儲存.* 如 type 是 REDIS_SET 類型的,如果其值可以表示成數字類型且 entry 小於配置值set-max-intset-entries, 則可以編碼成 REDIS_ENCODING_INTSET 類型儲存,以節約記憶體; 否則採用 Dict類型來儲存.* lru: 是時間戳記* refcount: 引用次數* void * ptr : 指向實際儲存的 value 值記憶體塊,其類型可以是 string, set, zset,list,hash ,編碼方式可以是上述 encoding 表示的一種.* 至於一個 key 的 value 採用哪種類型來儲存,完全是由用戶端的指令來決定的,如 hset ,則值是採用REDIS_HASH 類型表示的,至於那種編碼(encoding),則由 redis 根據配置自動決定.*/
1.2 Dict 結構
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/210203M04-0.jpg" style="border-top-width:1px;border-right-width:1px;border-bottom-width:1px;border-left-width:1px;border-top-style:solid;border-right-style:solid;border-bottom-style:solid;border-left-style:solid;text-align:center;background-color:#f3f3f3;padding:4px 5px 5px;margin:10px;" alt="Image011720.jpg" />
Dict 結構在<1.1Redis 記憶體儲存結構>; 已經描述過了,這裡不再贅述.
本文出自 “螞蟻窩” 部落格,請務必保留此出處http://feihan21.blog.51cto.com/1364153/1300016