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

2021-12-30 01:02:02 字數 1836 閱讀 1115

字典,是一種用於儲存鍵值對(key-value pair)的資料結構。

舉個例子,我們向redis中寫入:

msg就是鍵,「hello world」就是值,他們是一對鍵值對。

而許多這樣的鍵值對組合在一起就成了雜湊表。

redis的字典就是使用雜湊表作為底層實現,乙個雜湊表中存放多個雜湊表節點(每個節點儲存乙個鍵值對)。

redis字典使用的hash表結構如下:

table是乙個陣列,陣列中的每乙個元素都是指向乙個dict.h/dictentry結構,每個dict.h/dictentry儲存乙個鍵值對。

size記錄雜湊表(即table陣列)的大小,used屬性記錄雜湊表目前已經有的節點的數量。sizemask的值總是等於size-1,這個值會和鍵的hash值一起決定這個鍵對應的鍵值對該存放在什麼位置。

key儲存鍵值對中的鍵,v儲存這鍵值對中的值,鍵值對的值可以是乙個指標,或者是乙個uint64_t整數,或者是int64_t整數。

next屬性指向另乙個雜湊表節點,這個指標將多個雜湊值相同的鍵值對連線在一起,以此來解決鍵的衝突。

如下圖就是將衝突的鍵值對用next指標相連:

redis中的字典由dict.h/dict結構表示:

ht屬性是乙個包含兩個項的陣列,陣列中的每個項都是乙個dictht雜湊表,一般只是用ht[0],只有在對ht[0]進行rehash時才會使用ht[1]。rehashidx等於-1時表示目前沒有進行rehash。

隨著操作的不斷執行,雜湊表儲存的鍵值對會越來越多,如果衝突變多,導致鍊錶變長,查詢變慢,所以需要對雜湊表進行擴容。有擴容就有收縮,當雜湊表剩餘空間太多時,就會縮小雜湊表的空間。

擴容時會先為ht[1]申請足夠的空間:

然後將ht[0]中的每乙個鍵值對重新進行hash計算在ht[1]中找到對應的位置。

漸進式rehash

我們知道rehash是乙個耗時比較長的過程(鍵值對數量可能非常大),如果在這個過程中有新的操作需要向雜湊表中新增新的鍵值對,我們不會將它新增到ht[0],而是直接加到ht[1]。

下面看一下雜湊表漸進式rehahs的步驟:

漸進式rehash的好處在於不需要將龐大的工作量在同一時間完成,避免了集中式rehash的龐大計算量。

在進行漸進式rehash執行期間的雜湊表操作會在ht[0] ht[1]兩個表中操作。

比如要查詢乙個鍵,會先在ht[0]中找,沒有的話再到ht[1]中找。

總結:

Redis底層資料結構?

福哥口訣法 簡鏈字跳整 壓快壓 sds synamic string 簡單動態字串。支援自動動態擴容的位元組陣列 list 鍊錶 雙端鍊錶。dict 字典。使用雙雜湊表實現的,支援平滑擴容的字典 zskiplist 跳躍表。附加了後向指標的跳躍表 intset 整數集合。用於儲存整數數值集合的自有結...

Redis底層資料結構

redis底層實現的8種資料結構 sds synamic string 支援自動動態擴容的位元組陣列 list 鍊錶 dict 使用雙雜湊表實現的,支援平滑擴容的字典 zskiplist 附加了後向指標的跳躍表 intset 用於儲存整數數值集合的自有結構 ziplist 一種實現上類似於tlv,但...

redis底層資料結構

1.1 string字串 表現形式為 資料結構 sds 簡單的動態字串 使用原因 redis是使用c語言開發的,但在c語言中是沒有字串型別的,只能使用指標或符陣列的形式表示乙個字串,所以在redis設計了一種簡單的動態字串 可以根據不同的資料型別不同的資料結構選擇不同的資料結構 支援的資料型別 字串...