- 在字典中有兩個哈希桶來實現哈希的擴展; 在沒有對哈希進行擴張和rehash的情況下, 只有ht[0]來保存數據庫的鍵值; 在對哈希表進行擴展和rehash時,首先會將哈希桶擴大2倍,掛到ht[1]的哈希桶下面,並將rehashidx置爲0(表示開始從哈希桶的第一個桶開始進行rehash),然後逐漸將ht[0]哈希表上的數據轉移到ht[1]上。
- REDIS對哈希表進行rehash不是一次完成的,而是逐漸的對哈希表進行rehash的操作, REDIS的實現是在添加記錄時,對哈希表進行步值是1的rehash(即每添加一條記錄,對一個哈希桶(slot)做一次rehash的操作);
- REDIS啓動的一個定時任務來判斷是否需要對hash表進行resize操作, 如果需要resize(哈希表的使用率小於10% : used/size < 10%), 就需要減少哈希桶的數量; 並進行rehash的操作; 即使沒有對錶進行resize的操作, 如果主動rehash打開(activerehashing); 也會進行rehash的操作, 這種方式的rehash一般是已每步100slots的速度進行rehash的;不過一般是每次定時任務執行中在1毫秒內以100步爲單位進行, 每執行100步, 就判斷是否超過1毫秒,如果超過就不再進行rehash了。
- 在哈希表進行rehash的過程中, 對錶的操作要同時處理ht[0]和ht[1]兩張表, 一般插入是隻需對ht[1]操作就可以; 查找,刪除就需要對兩張表進行操作。
- 當節點rehash完畢後, 就需要將ht[1]指向的哈希桶賦給ht[0],ht[1]作爲下一次哈希桶擴展時用。
REDIS字典(dict)
REDIS用字典來實現鍵值的空間, 底層是由動態哈希來實現; 字典的結構如下面的圖
typedef struct dict
{
// 特定於類型的處理函數
dictType *type;
// 類型處理函數的私有數據
void *privdata;
// 哈希表(2個)
dictht ht[2];
// 記錄 rehash 進度的標誌,即正在對哪個桶節點做rehash,值爲-1 表示 rehash未進行
int rehashidx;
// 當前正在運作的安全迭代器數量
int iterators;
} dict;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.