10分鐘了解一致性哈希算法,全網(小區區域網)(建議收藏)

2021-01-09 前端程式設計師黃哥

很多同學應該都知道什麼是哈希函數,在後端面試和開發中會遇到「一致性哈希」,那麼什麼是一致性哈希呢?名字聽起來很厲害的樣子,其實原理並不複雜,這篇文章帶你徹底搞懂一致性哈希!

進入主題前,先來一場緊張刺激的模擬面試吧。

模擬面試

面試官:看你簡歷上寫參與了一個大型項目,用到了分布式緩存集群,那你說說你們是怎麼做緩存負載均衡?

萌新 :這個我知道,我們用的是輪詢方式,第一個key 給第一個存儲節點,第二個 key 給第二個,以此類推。

面試官:還有其他解決方案嗎?

萌新:可以用哈希函數,把請求打散隨機分配到緩存集群內機器。

面試官:考慮過這種哈希方式負載均衡的擴展性和容錯性嗎?

萌新:...

面試官:回去等通知吧。

以上如有雷同,算你抄我的。

什麼是哈希

數據結構中我們學習過哈希表也稱為散列表,我們來回顧下散列表的定義。

散列表,是根據鍵直接訪問在指定儲存位置數據的數據結構。通過計算一個關於鍵的函數也稱為哈希函數,將所需查詢的數據映射到表中一個位置來訪問記錄,加快查找速度。這個映射函數稱做「散列函數」,存放記錄的數組稱做散列表。

散列函數能使對一個數據序列的訪問過程更加迅速有效,是一種空間換時間的算法,通過散列函數數據元素將被更快定位。

下圖示意了字符串經過哈希函數映射到哈希表的過程。沒錯,輸入字符串是用臉滾鍵盤打出來的:)

常見的哈希算法有MD5、CRC 、MurmurHash 等算法。

MD5算法

MD5消息摘要算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數,可以產生出一個128位(16位元組)的散列值(hash value),MD5算法將數據(如一段文字)運算變為另一固定長度值,是散列算法的基礎原理。由美國密碼學家 Ronald Linn Rivest設計,於1992年公開並在 RFC 1321 中被加以規範。

CRC算法

循環冗餘校驗(Cyclic Redundancy Check)是一種根據網絡數據包或電腦文件等數據,產生簡短固定位數校驗碼的一種散列函數,由 W. Wesley Peterson 於1961年發表。生成的數字在傳輸或者存儲之前計算出來並且附加到數據後面,然後接收方進行檢驗確定數據是否發生變化。由於本函數易於用二進位的電腦硬體使用、容易進行數學分析並且尤其善於檢測傳輸通道幹擾引起的錯誤,因此獲得廣泛應用。

MurmurHash

MurmurHash 是一種非加密型哈希函數,適用於一般的哈希檢索操作。由 Austin Appleby 在2008年發明,並出現了多個變種,與其它流行的哈希函數相比,對於規律性較強的鍵,MurmurHash的隨機分布特徵表現更良好。

這個算法已經被很多開源項目使用,比如libstdc++ (4.6版)、Perl、nginx (不早於1.0.1版)、Rubinius、 libmemcached、maatkit、Hadoop等。

常見散列方法

直接定址法:取關鍵字或關鍵字的某個線性函數值為散列地址,這個線性函數的定義多種多樣,沒有標準。數字分析法:假設關鍵字是以r為基的數,並且哈希表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若干數位組成哈希地址。平方取中法:取關鍵字平方後的中間幾位為哈希地址。通常在選定哈希函數時不一定能知道關鍵字的全部情況,取其中的哪幾位也不一定合適,而一個數平方後的中間幾位數和數的每一位都相關,由此使隨機分布的關鍵字得到的哈希地址也是隨機的,取的位數由表長決定。摺疊法:將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進位)作為哈希地址。取模法:取關鍵字被某個不大於散列表表長 m 的數 p 除後所得的餘數為散列地址。即 hash(key) = key % p(p<= M),不僅可以對關鍵字直接取模,也可在摺疊法、平方取中法等運算之後取模。對 p 的選擇很重要,一般取素數或 m,若 p 選擇不好,容易產生衝突。緩存系統負載均衡

在分布式集群緩存的負載均衡實現中,比如 memcached 緩存集群,需要把緩存數據的 key 利用哈希函數散列,這樣緩存數據能夠均勻分布到各個分布式存儲節點上,要實現這樣的負載均衡一般可以用哈希算法來實現。下圖演示了這一分布式存儲過程:

普通哈希算法負載均衡

前面我們介紹過各種散列方法,不管是選擇上述哪種散列方法,在這個應用場景下,都是要把緩存數據利用哈希函數均勻的映射到伺服器集群上,我們就選擇簡單的「取模法」來說明這個過程。

假設有 3 個伺服器節點編號 [0 - 2],6 個緩存鍵值對編號 [1 - 6],則完成哈希映射之後,三個緩存數據映射情況如下:

哈希計算公式:key % 節點總數 = Hash節點下標1 % 3 = 12 % 3 = 23 % 3 = 04 % 3 = 15 % 3 = 26 % 3 = 0

每個連接都均勻的分散到了三個不同的伺服器節點上,看起來很完美!

但是,在分布式集群系統的負載均衡實現上,這種模型有兩個問題:

1. 擴展能力差

為了動態調節服務能力,服務節點經常需要擴容縮容。打個比方,如果是電商服務,雙十一期間的服務機器數量肯定要比平常大很多,新加進來的機器會使原來計算的哈希值不準確,為了達到負載均衡的效果,要重新計算並更新哈希值,對於更新後哈希值不一致的緩存數據,要遷移到更新後的節點上去。

假設新增了 1 個伺服器節點,由原來的 3 個服務節點變成 4 個節點編號 [0 - 3],哈希映射情況如下:

哈希計算公式:key % 節點總數 = Hash節點下標1 % 4 = 12 % 4 = 23 % 4 = 34 % 4 = 05 % 4 = 16 % 4 = 2

可以看到後面三個緩存 key :4、5、6 對應的存儲節點全部失效了,這就需要把這幾個節點的緩存數據遷移到更新後的節點上 (費時費力) ,也就是由原來的節點 [1, 2, 0] 遷移到節點 [0, 1, 2],遷移後存儲示意圖如下:

2. 容錯能力不佳

線上環境服務節點雖然有各種高可用性保證,但還是是有宕機的可能,即使沒有宕機也有縮容的需求。不管是宕機和縮容都可以歸結為服務節點刪除的情況,下面分析下服務節點刪除對負載均衡哈希值的影響。

假設刪除 1 個伺服器節點,由最初的 3 個服務節點變成 2 個,節點編號 [0 - 1],哈希映射情況如下:

哈希計算公式:key % 節點總數 = Hash節點下標1 % 2 = 12 % 2 = 03 % 2 = 14 % 2 = 05 % 2 = 16 % 2 = 0

下圖展示普通哈希負載均衡算法在一個節點宕機時候,導致的的緩存數據遷移分布情況:

如圖所見,在這個例子中,僅僅刪除了一個服務節點,也導致了哈希值的大面積更新,哈希值的更新也是意味著節點緩存數據的遷移(緩存數據表示心好累)。

一致性哈希算法負載均衡

正是由於普通哈希算法實現的緩存負載均衡存在擴展能力和容錯能力差問題,所以我們引入一致性哈希算法,那麼什麼是一致性哈希呢?先來看下wiki上對一致性Hash的定義

一致哈希由 MIT 的 David Karger 及其合作者提出,現在這一思想已經擴展到其它領域。在這篇1997年發表的學術論文中介紹了一致哈希如何應用於用戶易變的分布式Web服務中。一致哈希也可用於實現健壯緩存來減少大型Web應用中系統部分失效帶來的負面影響。

這篇描述一致性哈希的論文發表於1997年,閱讀無障礙的同學可以直接看看大佬的論文理解更深刻,附上論文下載連結:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.147.1879

一句話概括一致性哈希:就是普通取模哈希算法的改良版,哈希函數計算方法不變,只不過是通過構建環狀的 Hash 空間代替普通的線性 Hash 空間。具體做法如下:

首先,選擇一個足夠大的Hash空間(一般是 0 ~ 2^32)構成一個哈希環。

然後,對於緩存集群內的每個存儲伺服器節點計算 Hash 值,可以用伺服器的 IP 或 主機名計算得到哈希值,計算得到的哈希值就是服務節點在 Hash 環上的位置。

最後,對每個需要存儲的數據 key 同樣也計算一次哈希值,計算之後的哈希也映射到環上,數據存儲的位置是沿順時針的方向找到的環上的第一個節點。下圖舉例展示了節點存儲的數據情況,我們下面的說明也是基於目前的存儲情況來展開。

原理講完了,來看看為什麼這樣的設計能解決上面普通哈希的兩個問題。

擴展能力提升

前面我們分析過,普通哈希算法當需要擴容增加服務節點的時候,會導致原油哈希映射大面積失效。現在,我們來看下一致性哈希是如何解決這個問題的。

如下圖所示,當緩存服務集群要新增一個節點node3時,受影響的只有 key3 對應的數據 value3,此時只需把 value3 由原來的節點 node0 遷移到新增節點 node3 即可,其餘節點存儲的數據保持不動。

容錯能力提升

普通哈希算法當某一服務節點宕機下線,也會導致原來哈希映射的大面積失效,失效的映射觸發數據遷移影響緩存服務性能,容錯能力不足。一起來看下一致性哈希是如何提升容錯能力的。

如下圖所示,假設 node2 節點宕機下線,則原來存儲於 node2 的數據 value2 和 value5 ,只需按順時針方向選擇新的存儲節點 node0 存放即可,不會對其他節點數據產生影響。一致性哈希能把節點宕機造成的影響控制在順時針相鄰節點之間,避免對整個集群造成影響。

一致性哈希優化

存在的問題

上面展示了一致性哈希如何解決普通哈希的擴展和容錯問題,原理比較簡單,在理想情況下可以良好運行,但在實際使用中還有一些實際問題需要考慮,下面具體分析。

數據傾斜

試想一下若緩存集群內的服務節點比較少,就像我們例子中的三個節點,而哈希環的空間又有很大(一般是 0 ~ 2^32),這會導致什麼問題呢?

可能的一種情況是,較少的服務節點哈希值聚集在一起,比如下圖所示這種情況 node0 、node1、node2 聚集在一起,緩存數據的 key 哈希都映射到 node2 的順時針方向,數據按順時針尋找存儲節點就導致全都存儲到 node0 上去,給單個節點很大的壓力!這種情況稱為數據傾斜。

節點雪崩

數據傾斜和節點宕機都可能會導致緩存雪崩。

拿前面數據傾斜的示例來說,數據傾斜導致所有緩存數據都打到 node0 上面,有可能會導致 node0 不堪重負被壓垮了,node0 宕機,數據又都打到 node1 上面把 node1 也打垮了,node1 也被打趴傳遞給 node2,這時候故障就像像雪崩時滾雪球一樣越滾越大。

還有一種情況是節點由於各種原因宕機下線。比如下圖所示的節點 node2 下線導致原本在node2 的數據壓到 node0 , 在數據量特別大的情況下也可能導致節點雪崩,具體過程就像剛才的分析一樣。

總之,連鎖反應導致的整個緩存集群不可用,就稱為節點雪崩。

虛擬節點

那該如何解決上述兩個棘手的問題呢?可以通過「虛擬節點」的方式解決。

所謂虛擬節點,就是對原來單一的物理節點在哈希環上虛擬出幾個它的分身節點,這些分身節點稱為「虛擬節點」。打到分身節點上的數據實際上也是映射到分身對應的物理節點上,這樣一個物理節點可以通過虛擬節點的方式均勻分散在哈希環的各個部分,解決了數據傾斜問題。

由於虛擬節點分散在哈希環各個部分,當某個節點宕機下線,他所存儲的數據會被均勻分配給其他各個節點,避免對單一節點突發壓力導致的節點雪崩問題。

下圖展示了虛擬節點的哈希環分布,其中左邊是沒做虛擬節點情況下的節點分布,右邊背景色綠色兩個的 node0 節點是 node0 節點的虛擬節點;背景色紅色的 node1 節點是 node1 的虛擬節點。

總結一下

本文首先介紹了什麼是哈希算法和常見的哈希算法,以及常見散列方式,接著說明基於普通哈希算法的緩存負載均衡實現,並舉例說明普通算法的擴展性和容錯性方便存在的問題。

為了解決普通算法的擴展性和容錯性問題引入一致性哈希算法,圖解和舉例分析了一致性哈希是如何提高擴展性和容錯性。最後粗糙的一致性哈希算法也存在數據傾斜和節點雪崩的問題,講解了如何利用虛擬節點優化一致性哈希算法,解決數據傾斜和雪崩問題。至此,一致性哈希你學會了嗎?

再聊兩句(求三連)

感謝各位的閱讀,文章的目的是分享對知識的理解,技術類文章我都會反覆求證以求最大程度保證準確性,若文中出現明顯紕漏也歡迎指出,我們一起在探討中學習。

最後,咱給小編:

1. 點讚+評論

2. 點頭像關注,轉發給有需要的朋友。

謝謝!!

相關焦點

  • 什麼是一致性哈希算法
    這裡主要記錄一致性Hash算法如何將數據分配到各個機器中去。2,衡量一致性哈希算法好處的四個標準①平衡性。平衡性是指哈希的結果能夠儘可能分布到所有的緩衝中去,這樣可以使得所有的緩衝空間都得到利用。②單調性。單調性是指如果已經有一些數據通過哈希分配到了相應的機器上,又有新的機器加入到系統中。
  • 一口氣講透一致性哈希(Hash),助力「碼農變身」
    如今雲計算、大數據、物聯網、AI的興起,使得分布系統得到了前所未有的廣泛應用,然而由於分布式系統具有極高的複雜度,帶來了許多難題,一致性哈希就是為了解決分布式難題之一應運而生的,本篇主要圖示講解一致性哈希的原理及其應用,助力碼農變身。
  • 從哈希函數、哈希衝突、開散列出發,一文告訴你哈希思想與哈希表構造到底是什麼!
    ,是把任意長度的輸入(又叫做預映射pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。哈希函數散列函數(英語:Hash function)又稱散列算法、哈希函數,是一種從任何一種數據中創建小的數字「指紋」的方法。
  • 機器學習時代的哈希算法,將如何更高效地索引數據
    哈希算法一直是索引中最為經典的方法,它們能高效地儲存與檢索數據。但在去年 12 月,Jeff Dean 與 MIT 等研究者將索引視為模型,探索了深度學習模型學習的索引優於傳統索引結構的條件。本文首先將介紹什麼是索引以及哈希算法,並描述在機器學習與深度學習時代中,如何將索引視為模型學習比哈希算法更高效的表徵。
  • 哈希算法、愛因斯坦求和約定,這是2020年的注意力機制
    哈希算法、Head 之間的信息交流都需要考慮,顯存佔用、表徵能力都不能忽視。注意力機制是非常優美而神奇的機制,在神經網絡「信息過載」的今天,讓 NN 學會只關注特定的部分,無疑會大幅度提升任務的效果與效率。藉助注意力機制,神經機器翻譯、預訓練語言模型等任務獲得了前所未有的提升。
  • 受果蠅啟發的哈希算法!用「生物學上合理的」突觸可塑性規則生成...
    這個算法的靈感來自於果蠅的嗅覺迴路,它可以產生哈希碼——物體的數字表示——其性能優於經典算法。不幸的是,由於FlyHash使用隨機投影,它無法從數據中學習。他們說,它比之前發布的各種哈希方法的基準測試都要好,而且它可以生成對相似度搜索有用的二進位表示。
  • 北京郵電大學「區域網」聽課筆記(1-3章)
    1.1.2區域網的定義    在一個小區範圍內,將分散的微機系統互連起來,實現資源的共享合同型,便構成了區域網    (LAN)。幾點說明:    (1)區域網終端設備:又稱為數據通信設備。主要包括:微機、伺服器、終端、外圍設備、傳感器(如溫度、溼度、安全報警傳感器等),數字電話、數位電視發送和接收機以及傳真機等。
  • 人們常說的哈希(Hash)到底是什麼?
    了解過區塊鏈的朋友,一定聽過「哈希」這一詞彙,然而對哈希的概念又極其的模糊,那麼哈希是什麼呢?Hash一般被翻譯成「散列」,也可直接音譯為「哈希」,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。
  • 基於USB接口的區域網接入適配器的設計方案
    這塊晶片是一塊高度集成的10BASE-T/100BASE-TX/FX的乙太網收發晶片。RTL8204包括了四個獨立的通道,可以同時收發四路乙太網信號,每路通道都集成了4B5B編解碼器、曼徹斯特編解碼器、加擾器、解擾器、輸出驅動、輸出波形形成、濾波、數字自適應均衡和鎖相環模塊。但在本系統中只用了一路連接外部區域網。
  • 她任教山東大學,後被清華聘請,破解國際通用哈希函數而出名
    在中國有一位這樣女教授,她破解了世界上著名的通用哈希函數,就好比一個人赤手空拳,在一天之內造出一架飛機飛上天!讓我們來一起了解王小雲教授吧。1966年,王小雲出生在山東省的諸城。一年多以後,潘承洞發現王小雲更擅長密碼學方向的研究,建議她轉攻密碼學。王小雲聽從了老師的建議,開始了她艱苦研究的密碼學歷程。又過幾年,王小雲考上基礎數學專業的博士,並在本校擔任老師。王小雲開始自己一個人埋頭研究密碼,一研究就是十年!而且當時國家並沒有給予相關的經費支持,這樣簡劣的條件下,王小雲沒有放棄,沉浸在知識的象牙塔裡。
  • 區塊鏈加密機制的不同算法及其原理解析
    礦工在處理交易數據(對數據也是進行哈希)的同時不斷的進行哈希計算,求得一位前23位為0的哈希值,這個值成為nonce黃金數。當全網有一位礦工哈希出nonce時,他就會把自己打包的區塊公布出去,其他節點收到區塊驗證區塊後就會一致性認為這個區塊接到了區塊鏈上,就繼續進行下一個區塊的打包和哈希計算。
  • Comunion 區塊鏈深度學習系列|什麼是哈希
    比如特工A和特工B在進行信息交換,為了防止數據在傳輸的過程中沒有被丟失或者被篡改,這個時候可以使用哈希算法。特工A將其所發的信息進行哈希,然後將信息和哈希碼一起傳給特工B,特工B收到之後,也可以對文本進行哈希,然後和這個哈希碼進行匹配,如果匹配上的話,說明信息在傳播的過程當中沒有丟失或者被篡改。
  • 「新」動時刻, 讓你心中的哈希最強新品C位出道
    環境應急等領域• TX1315可攜式生物毒性分析儀不僅可用於發光細菌法生物毒性分析,還可用於化學發光毒性法分析;具有突破性的微生物檢測技術,只需幾分鐘就能獲得關鍵數據,內置於現場端工控機內,基於不斷優化的算法實時監控水質數據與儀表狀態、提前預警水質情況,可根據用戶需求定製軟體端展示內容,為決策部門及時制定解決方案提供更充足的時間。
  • 哈達瑪矩陣指導下的在線哈希學習新方法
    不同於基於樹的索引將數據空間進行遞歸的劃分,哈希類算法重複的對整個數據空間進行二類劃分,同時對於每一個劃分進行一次二值編碼。即哈希算法將輸入數據映射到一個離散的漢明空間,每一個數據點用一串二值碼表示。漢明距離可以通過異或操作進行快速計算,因此使用哈希碼對資料庫進行窮盡檢索,時間複雜度也能滿足應用要求。
  • 2019.01:小區「15分鐘社區生活圈」空間聚類研究——基於POI數據...
    藉助本研究的成果,可以全面了解北京市在打造「15分鐘社區生活圈」中的薄弱環節,為優化公共資源的空間投入和布局提供決策參考。8個方面,用來評估各小區「15分鐘社區生活圈」的發展水平。但由於當前對「15分鐘社區生活圈」的研究和實踐更多的是理論層面和指導意見層面,缺乏公認的評估標準和體系,更沒有從「生活圈」視角量化評估小區的研究成果。
  • 主宰全球的10大算法
    【編者按】Reddit有篇帖子介紹了算法對我們現在生活的重要性,以及哪些算法對現代文明所做貢獻最大。這個表單並不完整,很多與我們密切相關的算法都沒有提到,如機器學習和矩陣乘法,歡迎你繼續補充。如果對算法有所了解,讀這篇文章時你可能會問「作者知道算法為何物嗎?」,或是「Facebook的『信息流』(News Feed)算是一種算法嗎?」
  • 區域網網速突然變慢怎麼辦
    區域網網速變慢是怎麼回事呢?通常這是由於區域網中有人使用限速軟體所造成的,由於限制軟體大都通過ARP方式實現限速。因此我們可以通過以下方法查找區域網中使用限速軟體的電腦,同時利用適合的方法破解限速軟體對網速的限制。以下就是具體的實現方法。
  • 2018年自考「區域網技術與組網工程」模擬題(5)
    在傳輸介質中雙絞線的抗電磁幹擾最差C、同軸電纜分為50歐姆和75歐姆兩種D、集線器是用於雙絞線的聯接2、下列不屬於網橋的是( )A、透明橋 B、路源橋 C、對話橋 D、打包橋3、IEEE802工程標準中的802.3協議是( )A、區域網的載波偵聽多路訪問標準B、區域網的令牌環網標準C、區域網的令牌總線標準
  • 五分鐘了解機器學習十大算法
    本文為有志於成為數據科學家或對此感興趣的讀者們介紹最流行的機器學習算法。機器學習是該行業的一個創新且重要的領域。我們為機器學習程序選擇的算法類型,取決於我們想要實現的目標。現在,機器學習有很多算法。因此,如此多的算法,可能對於初學者來說,是相當不堪重負的。