Redis的字典結構底層設計

2021-09-02 23:52:34 字數 1272 閱讀 1669

相比前兩種sds和list結構而言,字典的結構相對來說要複雜,主要涉及的都是和雜湊相關的問題,包括但不限於雜湊衝突的解決。雜湊的擴容策略,雜湊演算法等。其主要用在redis的底層資料庫底層實現雜湊鍵的底層實現

ht屬性是乙個包含兩個項的陣列,陣列中的每個項都是乙個dictht雜湊表,一般情況下,字典只使用ht[0]雜湊表,ht[1]雜湊表只會在對ht[0]雜湊表進行rehash時使用。

除了ht[1]之外,另乙個和rehash有關的屬性就是rehashidx,它記錄了rehash目前的進度,如果目前沒有在進行rehash,那麼它的值為-1.。

下圖展示了普通狀態下(沒有進行rehash)的字典結構。

當向字典中新增乙個鍵值對時,會根據雜湊演算法將其插入到指定位置。通常採用的是murmurhash演算法.常見的方法還有逐位異或或者按位取與運算。當增加的鍵值對過多時,難免會導致不同鍵計算出的雜湊值一致,即有2個或2個以上的鍵被分配到雜湊表陣列的同乙個索引上面。這就產生了雜湊衝突。解決衝突常用的方法是鏈位址法。

隨著操作的不斷執行,雜湊表儲存的鍵值對會逐漸地增多或者減少,為了讓雜湊表的負載因子(load factor)維持在乙個合理的範圍內,當雜湊表儲存的鍵值對數量太多或者太少時,程式需要對雜湊表的大小進行相應的擴充套件或者收縮。

擴充套件和收縮雜湊表的工作可以通過執行rehash(重新雜湊)操作來完成,redis對字典的雜湊表執行rehash的步驟如下:

1)為字典的ht[1]雜湊表分配空間,這個雜湊表的空間大小取決於要執行的操作,以及ht[0]當前包含的鍵值對數量(也即是ht[0].used屬性的值):

2)將儲存在ht[0]中的所有鍵值對rehash到ht[1]上面,rehash值的是重新計算鍵的雜湊值和索引值,然後將鍵值對放置到ht[1]雜湊表的指定位置上。

3)當ht[0]包含的所有鍵值對都遷移到了ht[1]之後(ht[0]變為空表),釋放ht[0],jiang ht設定為ht[0],並在ht[1]新建立乙個空白雜湊表,為下一次rehash做準備。

上面的rehash操作不是一致性,集中式地完成。而是分多次,漸進式完成。這樣做的好處是避免rehash對伺服器效能造成影響。

Redis底層學習之資料結構字典

字典,是一種用於儲存鍵值對 key value pair 的資料結構。舉個例子,我們向redis中寫入 msg就是鍵,hello world 就是值,他們是一對鍵值對。而許多這樣的鍵值對組合在一起就成了雜湊表。redis的字典就是使用雜湊表作為底層實現,乙個雜湊表中存放多個雜湊表節點 每個節點儲存乙...

redis底層設計(二) 記憶體對映資料結構

上篇我們講了內部資料結構,雖然內部資料結構非常強大,但是建立一系列完整的資料結構本身也是一件相當耗費時間的工作,當乙個物件包含的元素數量並不多,或者元素本身的體積並不大時,使用代價高昂的內部資料結構並不是最好的辦法。因此我們會用記憶體對映資料結構來代替內部資料結構。記憶體對映資料結構是一系列經過特殊...

Redis字串的底層設計

redis的底層是用c語言來實現的,在c語言中字串的預設是以 0 標識結束,而redis並沒有採用這種傳統的方法表示,而是自己構建了一種簡單動態字串 sds 來表示。下面看一下什麼是sds,sds的 定義,以及在儲存乙個字串 redis 時sds和傳統c的表示分別是怎麼樣,使用sds的好處是什麼 s...