溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

發(fā)布時間:2022-01-04 16:41:10 來源:億速云 閱讀:128 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的”吧!

哈希類型內(nèi)部編碼詳情

對于 Redis的常用 5 種數(shù)據(jù)類型(String、Hash、List、Set、sorted set),每種數(shù)據(jù)類型都提供了 最少兩種 內(nèi)部的編碼格式,而且每個數(shù)據(jù)類型內(nèi)部編碼方式的選擇 對用戶是完全透明的,Redis會根據(jù)數(shù)據(jù)量自適應(yīng)地選擇較優(yōu)化的內(nèi)部編碼格式。

如果想查看某個鍵的內(nèi)部編碼格式,可以使用 OBJECT ENCODING keyname 指令來進行,比如:

127.0.0.1:6379> 
127.0.0.1:6379> set foo bar
OK127.0.0.1:6379> 
127.0.0.1:6379> object encoding foo // 查看某個Redis鍵值的編碼"embstr"127.0.0.1:6379> 
127.0.0.1:6379>

對于使用最為頻繁的 Hash類型,其內(nèi)部編碼方式可能有兩種:

  • OBJ_ENCODING_ZIPLIST(壓縮列表)

  • OBJ_ENCODING_HT(哈希表)

Redis 會根據(jù)數(shù)據(jù)量的情況來自適應(yīng)地選擇這兩種編碼方式中 較優(yōu) 的一種,而這一切對用戶完全透明。

在 數(shù)據(jù)條目較少,數(shù)據(jù)值較小 的時候 Redis會采用 壓縮列表(OBJ_ENCODING_ZIPLIST)編碼方式進行存儲。這里成員"較少",成員值"較小"的標準可以通過如下配置項進行配置:

hash-max-ziplist-entries 512hash-max-ziplist-value 64

Redis 默認給出了默認值,當(dāng)然用戶可根據(jù)實際情況自行配置。

當(dāng) Hash類型鍵的字段個數(shù) < hash-max-ziplist-entries 并且 每個字段名和字段值的長度 < hash-max-ziplist-value 時,Redis 會使用 OBJ_ENCODING_ZIPLIST來存儲該鍵,反之則會轉(zhuǎn)換為 OBJ_ENCODING_HT的編碼方式。

口說無憑,我們不妨先來做個實驗感受一下吧:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

很明顯該實驗驗證了當(dāng) 字段值長度大于64時,編碼格式會由 ZIPLIST方式切換為 Hashtable方式。

源碼之前,了無秘密,我們再來看一下Redis關(guān)于這部分切換的源碼實現(xiàn),那就理解得更加清楚了:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

下面詳解 OBJ_ENCODING_ZIPLIST 和 OBJ_ENCODING_HT 這兩種編碼格式的內(nèi)部存儲模型,知道了其各自特點和優(yōu)缺點,自然也就明白了Redis內(nèi)部使用它們的意圖。


OBJ_ENCODING_ZIPLIST 編碼

Ziplist 壓縮列表是一種緊湊編碼格式,總體思想是時間換空間,即以部分讀寫性能為代價,來換取極高的內(nèi)存空間利用率,因此只會用于 字段個數(shù)少,且字段值也較小 的場景。給大家推薦一個架構(gòu)交流群:698581634 進群即可免費獲取資料。

壓縮列表內(nèi)存利用率極高的原因與其連續(xù)內(nèi)存的特性是分不開的,其典型的內(nèi)存結(jié)構(gòu)可以用下圖形象地展示出來:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

所以如果用 Ziplist來存儲 Redis的散列類型的話,元素的排列方式就變成了如下圖所示的形象示意圖:即key和value都是邏輯連續(xù)內(nèi)存:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的


OBJ_ENCODING_HT 編碼

OBJ_ENCODING_HT 這種編碼方式內(nèi)部才是真正的哈希表結(jié)構(gòu),或稱為字典結(jié)構(gòu),其可以實現(xiàn)O(1)復(fù)雜度的讀寫操作,因此效率很高。

在 Redis內(nèi)部,從 OBJ_ENCODING_HT類型到底層真正的散列表數(shù)據(jù)結(jié)構(gòu)是一層層嵌套下去的,關(guān)系如下:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

這一關(guān)系我們可以從 Redis哈希表定義部分的源碼來看出:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

下面來詳解一下各個部分:

  • 關(guān)于哈希節(jié)點(dictEntry)

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

  • 關(guān)于哈希表(dictht)和字典(dict)

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

  • 關(guān)于dictType

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

  • Redis如何計算Hash值

Redis計算Hash的源代碼如下:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

這是一個 C語言宏定義,其實幕后真正承擔(dān) Hash值計算的是上面介紹的 dictType結(jié)構(gòu)體中的函數(shù)指針 hashFunction。給大家推薦一個架構(gòu)交流群:698581634 進群即可免費獲取資料。

而該 hashFunction函數(shù)指針在初始化時會對應(yīng)被賦值為一個個真實的計算 Hash值的實際函數(shù),就像下面這樣:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

  • Redis如何計算存取索引Index值

Index值的計算依賴于上面計算得出的 Hash值,代碼如下:

Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的

到此,相信大家對“Redis哈希結(jié)構(gòu)內(nèi)存模型是怎樣的”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI