Redis的設計與實現 字典

2022-02-13 12:07:45 字數 1313 閱讀 9157

參考部落格

絕大多數語言中的字典底層實現基本上都是雜湊表。雜湊表中用 「負載因子」 來衡量雜湊表的空/滿程度。為了讓負載因子在一定的合理範圍之內,提高查詢的效能,一般的做法是讓雜湊表擴容,然後rehash一把。

but,擴容也不一定就能解決負載因子過大的問題。redis作為一款成熟的非關係型資料庫,肯定有他的獨到解決辦法!!!能夠保證rehash是有效的。

講解rehash之前看下redis裡面的一些資料結構:字典的底層有雜湊表實現,ht存放的是雜湊表。

redis對字典的rehash的步驟如下:

①為字典的ht[1]分配空間,空間的大小取決於要執行的操作(擴充套件還是收縮)以及ht[0]的used屬性。

擴充套件:ht[1]的大小為第乙個大於等於ht[0].used*2  的 2n。

收縮:ht[1]的大小為第乙個大於等於ht[0].used      的 2n。

②將ht[0]裡面的鍵值對rehash到ht[1]。

③都遷移到ht[1]之後,釋放ht[0],將ht[1]設定為ht[0],然後在ht[1]新建空白雜湊表。為下一次rehash做準備。

寫道這裡,我還是沒有搞清楚這個redis的雜湊設計高效在**?直到我看到了漸進式hash!!!

漸進式hash

何為漸進式hash?在上面提到的rehash中,不是一次性將ht[0]的資料送入ht[1],如果資料量過大,將會嚴重影響redis資料庫的效能,所以採用了一種方法漸進式。

漸進式具體操作呢?

①給ht[1]分配空間,讓字典同時持有兩個雜湊表ht[0]和ht[1]。

②利用乙個巧妙地資料設計,rehashidx,初值設為-1,表示不需要rehash;一旦需要rehash的時候,設定為0,表示rehash工作正式開始。

③在rehash進行期間,除了執行指定的操作(增刪改查)之外,還會附加做一些工作,就是將ht[0]上的rehashidx對應的所有鍵值對rehash到ht[1]上,移完之後,rehashidx加1.

④隨著字典操作(增刪改查)的不斷執行,最終會在某個時間點上,ht[0]的所有鍵值對都會被rehash到ht[1]上,這時程式將rehashidx設定為-1,表示rehash操作已全部完成。rehash的過程中,新增操作只會在ht[1]上進行,這樣能夠保證ht[0]的鍵值對只減不增。

漸進式rehash操作的好處是,避免了集中式rehash操作,將rehash的操作分攤到每次的資料庫操作上。

Redis設計於實現之字典

簡介 字典實現 字典的實現是以雜湊表作為它的底層實現,乙個雜湊表可以有多個雜湊表節點,每個節點儲存了字典中的乙個鍵值對。1.雜湊表節點 key就是鍵,v就是鍵中的值 可以是指標,unit64 t 整數,int64 t s64整數 next是將另外乙個雜湊值相同的鍵值對連線在一起的指標 為了解決衝突 ...

Redis 設計與實現

本書的目標是以簡明易懂的方式講解 redis 的內部執行機制,通過閱讀本書,你可以了解到 redis 從資料結構到伺服器構造在內的幾乎所有知識。為了保證內容的簡潔性,本書會盡量以高抽象層次的角度來觀察 redis 並將 的細節留給讀者自己去考究。如果讀者只是對 redis 的內部運作機制感興趣,但並...

redis設計與實現

物件所使用的底層資料結構 編碼常量 object encoding 命令輸出 整數redis encoding int int embstr編碼的簡單動態字串 sds redis encoding embstr embstr 簡單動態字串 redis encoding raw raw 字典redis...