面試官:Redis中哈希數據類型的內部實現方式是什麼?

  • 2022 年 3 月 11 日
  • 筆記

面試官:Redis中基本的數據類型有哪些?

我:Redis的基本數據類型有:字元串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。

面試官:哈希數據類型的內部實現方式是什麼?

我還沉浸在上一個問題的沾沾自喜中,頓時表情凝固了,手心開始冒出冷汗。「這個。。沒有太深入了解」,我支支吾吾的說到。

面試官:回去等消息吧。

這句話說的乾淨利落,然後就沒有然後了。失敗是成功的媽媽,我不氣餒,決定馬上惡補一下。

哈希的編碼

哈希的編碼有兩種,分別是壓縮列表(ziplist)和哈希表(hashtable)。當所有鍵值對的鍵和值的長度都小於hash-max-ziplist-value(默認為64位元組),並且鍵值對的數量小於hash-max-ziplist-entries(默認為512個)的時候,哈希就會使用壓縮列表作為編碼,否則使用哈希表作為編碼。

我們來舉個例子:

127.0.0.1:6379> hset one-more-hash name "萬貓學社"
(integer) 1
127.0.0.1:6379> hset one-more-hash gender "男"
(integer) 1
127.0.0.1:6379> object encoding one-more-hash
"ziplist"

此時,所有鍵值對的鍵和值的長度和鍵值對的數量都比較小,哈希使用壓縮列表作為編碼。我們再加入一個值比較大的鍵值對:

127.0.0.1:6379> hset one-more-hash introduce "Java領域優質創作者、CSDN部落格專家認證"
(integer) 1
127.0.0.1:6379> object encoding one-more-hash
"hashtable"

此時,哈希的編碼由壓縮列錶轉化為編碼。

當然,了解以上細節還沒能完全「征服」面試官,我們需要更深入一些:)

哈希的底層實現

當壓縮列表作為哈希的編碼時,有新的鍵值對加入到哈希數據類型中,先把鍵的壓縮列表節點添加到壓縮列表的末尾,然後再把值的壓縮列表節點添加到壓縮列表的末尾。

所以,在哈希數據類型的壓縮列表中,先加入的鍵值對在壓縮列表的頭部方向,後加入的鍵值對在壓縮列表的末尾方向;同一個鍵值對的兩個節點是緊挨在一起的,鍵的節點在前,值的節點在後。

壓縮列表使用更加緊湊的記憶體結構實現多個鍵值對的連續存儲,在節省記憶體方面比哈希表表現的更加優秀。

當哈希表作為哈希的編碼時,每個鍵值對都使用一個字典鍵值對保存,字典的每個鍵都是一個字元串對象,對象中保存鍵值對的鍵;字典的每個值也都是一個字元串對象,對象中保存鍵值對的值。

哈希表雖然沒有壓縮列表節省記憶體,但是它的讀寫時間複雜度為O(1),在時間效率方面比壓縮列表表現的更加優秀。

總結

哈希數據類型的內部實現有壓縮列表(ziplist)和哈希表(hashtable)兩種。當哈希數據類型的鍵和值的長度較小並且鍵值對數量較少時,使用壓縮列表作為內部實現,否則使用哈希表作為內部實現。

最後,謝謝你這麼帥,還給我點贊關注

微信公眾號:萬貓學社

微信掃描二維碼

關注後回復「電子書」

獲取12本Java必讀技術書籍