給面試官講明白:一致性Hash的原理和實踐

靳剛同學發表於2019-08-12

“一致性hash的設計初衷是解決分散式快取問題,它不僅能起到hash作用,還可以在伺服器當機時,儘量少地遷移資料。因此被廣泛用於狀態服務的路由功能”

01分散式系統的路由演算法

假設有一個訊息推送系統,其簡易架構如下

系統簡易架構圖
)

裝置接入層不僅要接收裝置的登入、下線等狀態命令,還要把開發者的訊息推送給裝置。這個時候裝置接入層就需要維護裝置的狀態資訊(當然可以專門拆一個狀態服務去維護這些資訊,要求這部分必須少有程式碼更新,具體原因自己去想哦=_=)。這個時候裝置接入層的每臺server都保留一批裝置的狀態資訊cache,裝置應該連線哪臺server去獲取資料,同時中間層的訊息又該發往哪個server去推送呢?這就用到了一致性hash演算法。

02什麼是一致性hash演算法

一致性hash由物件、資源、演算法和機器組成。它要做的是:物件通過演算法判斷連哪臺機器。在如上系統中:裝置id(userID)為物件;其對應的狀態資料(cache)為資源;伺服器為機器。

一致性hash

在一致性hash演算法中,這些資源圍成了一個閉環,每臺機器又儲存著一個資源段,每個資源段對應一批物件/裝置;這樣如果某臺機器掛了,那它對應的資源轉移到離它較近的機器x,這臺dead server對應的裝置連線到機器x就行。
現在假設這四個資源段對應的裝置,活躍情況相差較大。比如說資源段1、2對應的裝置特別活躍,而資源段3和4幾乎沒活動。這樣機器1-2需要儲存大量的狀態資料,而3-4則有大量的空置,顯然是不合理的。改進版的一致性hash演算法是這樣操作的:它不再是每臺機器去儲存一個連續的資源段,而是讓每臺機器都儲存多個區域的部分資源段。如機器1儲存每個資源段的1/4,機器2儲存每個資源段的1/4,機器3、4同樣如此。這樣即使個別號段有熱點,也會均攤到不同的機器。
一致性hash改進版

03一致性hash在系統中的應用

如上介紹了一致性hash的概念和改進,在系統實踐中,我們使用者量非常大,往往不只一個叢集。我們是如此使用一致性hash:

  • 首先根據不同號段選擇對應的叢集,這部分是可配置的

  • 確定叢集后,根據一致性hash把裝置匹配到server的某個instance上(每臺server部署多個裝置接入層例項(1.每個instance儲存的狀態資訊更分散;2.服務的gc問題會有緩解)

  • 建立機器虛擬節點:把user逆序(打亂之前連續userId),組成新的資源段;相當於建立了server虛擬節點

  • 記錄每臺server鎖服務的裝置數,如果機器A掛了,挑選服務裝置數最少的機器去承接kicked-device

04不是所有情況都適合一致性hash

以上介紹了一致性Hash的原理和實踐,但不是所有的服務都適合用一致性hash來路由。比如01節中的訊息推送系統,中間層是無狀態的,開發者接入層請求cluter-A的哪臺機器都行,它只要做完基本校驗後,把訊息非同步發給MQ即可,無需等待結果直接返回; 而裝置接入層是有狀態的,且對較高時延無法忍受,更適合一致性Hash選擇好server-instance,然後通過TCP/UDP來通訊。

如果喜歡我的文章,請長按二維碼,關注靳剛同學

給面試官講明白:一致性Hash的原理和實踐

您的轉發是對我最大的支援,謝謝!
長按訂閱更多精彩▼

相關文章