Redis實現原理(2)--字典

來源:互聯網
上載者:User

標籤:des   style   blog   color   使用   io   資料   cti   

1、   Dict    

2.1 資料結構定義dict.h

// 雜湊表結構typedef struct dictht {    dictEntry **table; //雜湊表數組指標    unsigned long size;  //雜湊表大小    unsigned long sizemask; //掩碼,hash時用到    unsigned long used; //已有節點的數量} dictht;//  雜湊表節點結構typedef struct dictEntry {    void *key;     union {        void *val;        uint64_t u64;        int64_t s64;    } v;  // 值,可以是指標類型、uint64和int64    struct dictEntry *next;  //指向下一節點形成一個單鏈表} dictEntry;//字典定義typedef struct dict {    dictType *type;    void *privdata;    dictht ht[2];    int rehashidx; // 重分布標示-1標示正在重分布中    int iterators; // 重分布進度} dict;// 字典類型// 每個dictType儲存了一系列用於操作特定字典的函數,不同用途的字典type不同typedef struct dictType {       // hash函數unsigned int (*hashFunction)(const void *key);// key的複製void *(*keyDup)(void *privdata, const void *key);// value的複製void *(*valDup)(void *privdata, const void *obj);// key的比較int (*keyCompare)(void *privdata, const void *key1, const void *key2);// key的銷毀void (*keyDestructor)(void *privdata, void *key);// value的銷毀    void (*valDestructor)(void *privdata, void *obj);} dictType;

 

2.2 hash

調用type中得hashFunction方法計算key的hash值,redis內部使用的hash演算法為Austin Appleby開發的MurmurHash2演算法

h = d->type->hashFunction(key)

計算key的索引值,先在ht[0]中尋找,如果沒有找到並且在rehash的過程中,則繼續在ht[1]中找

idx = h & d->ht[table].sizemask

對於雜湊衝突的解決,redis採取的拉鏈法,相同索引值的key會儲存在一個單鏈表中,所以確定了索引值以後還需要在對應的單鏈表中進行搜尋

while(he) {            if (dictCompareKeys(d, key, he->key))                return -1;            he = he->next;        }

 

2.3 rehash

為了保證字典的使用效率,redis對字典結構採取了定期rehash的機制,因為rehash是重CPU的操作,為了避免過程中出現對外無響應的情況,這裡做了一種增量rehash的最佳化

rehash的流程如下:

1)   建立一個空得hash表,size為第一個大於等於2n的整數

unsigned long i = DICT_HT_INITIAL_SIZE;if (size >= LONG_MAX) return LONG_MAX;while(1) {    if (i >= size)       return i;    i *= 2;}

 

2)   將ht[0]中的key重新計算hash和index,索引到ht[1]中,並將ht[0]中相應的索引值置為空白

3)   待ht[0]中的資料全部rehash到ht[1]中之後將ht[1]設定為ht[0],並建立一個新的ht[1]

增量rehash是對步驟2進行最佳化,每次只rehash一個index的key,並且在rehash過程中對讀寫操作做限制:

1)      讀:先查ht[0],如果沒有再在ht[1]上尋找

2)      寫:rehash過程中,新的key只向ht[1]中寫,並且會將索引所對應的所有key重新hash到ht[1]中。

最終會在某個時間點ht[0]中所有的key重新hash到ht[1]中。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.