一致性雜湊演算法及其在分布式系統中的應用

來源:互聯網
上載者:User

摘要

本文將會從實際應用情境出發,介紹一致性雜湊演算法(Consistent Hashing)及其在分布式系統中的應用。首先本文會描述一個在日常開發中經常會遇到的問題情境,藉此介紹一致性雜湊演算法以及這個演算法如何解決此問題;接下來會對這個演算法進行相對詳細的描述,並討論一些如虛擬節點等與此演算法應用相關的話題。

分布式緩衝問題

假設我們有一個網站,最近發現隨著流量增加,伺服器壓力越來越大,之前直接讀寫資料庫的方式不太給力了,於是我們想引入Memcached作為緩衝機制。現在我們一共有三台機器可以作為Memcached伺服器,如所示。

很顯然,最簡單的策略是將每一次Memcached請求隨機發送到一台Memcached伺服器,但是這種策略可能會帶來兩個問題:一是同一份資料可能被存在不同的機器上而造成資料冗餘,二是有可能某資料已經被緩衝但是訪問卻沒有命中,因為無法保證對相同key的所有訪問都被發送到相同的伺服器。因此,隨機策略無論是時間效率還是空間效率都非常不好。

要解決上述問題只需做到如下一點:保證對相同key的訪問會被發送到相同的伺服器。很多方法可以實現這一點,最常用的方法是計算雜湊。例如對於每次訪問,可以按如下演算法計算其雜湊值:

h = Hash(key) % 3

其中Hash是一個從字串到正整數的雜湊映射函數。這樣,如果我們將Memcached Server分別編號為0、1、2,那麼就可以根據上式和key計算出伺服器編號h,然後去訪問。

這個方法雖然解決了上面提到的兩個問題,但是存在一些其它的問題。如果將上述方法抽象,可以認為通過:

h = Hash(key) % N

這個算式計算每個key的請求應該被發送到哪台伺服器,其中N為伺服器的台數,並且伺服器按照0 – (N-1)編號。

這個演算法的問題在於容錯性和擴充性不好。所謂容錯性是指當系統中某一個或幾個伺服器變得不可用時,整個系統是否可以正確高效運行;而擴充性是指當加入新的伺服器後,整個系統是否可以正確高效運行。

現假設有一台伺服器宕機了,那麼為了填補空缺,要將宕機的伺服器從編號清單中移除,後面的伺服器按順序前移一位並將其編號值減一,此時每個key就要按h = Hash(key) % (N-1)重新計算;同樣,如果新增了一台伺服器,雖然原有伺服器編號不用改變,但是要按h = Hash(key) % (N+1)重新計算雜湊值。因此系統中一旦有伺服器變更,大量的key會被重定位到不同的伺服器從而造成大量的緩衝不命中。而這種情況在分布式系統中是非常糟糕的。

一個設計良好的分布式雜湊方案應該具有良好的單調性,即服務節點的增減不會造成大量雜湊重定位。一致性雜湊演算法就是這樣一種雜湊方案。

一致性雜湊演算法演算法簡述

    一致性雜湊演算法(Consistent Hashing)最早在論文《Consistent
Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》中被提出。簡單來說,一致性雜湊將整個雜湊值空間組織成一個虛擬圓環,如假設某雜湊函數H的值空間為0 - 232-1(即雜湊值是一個32位無符號整形),整個雜湊空間環如下:

    整個空間按順時針方向組織。0和232-1在零點中方向重合。

    下一步將各個伺服器使用H進行一個雜湊,具體可以選擇伺服器的ip或主機名稱作為關鍵字進行雜湊,這樣每台機器就能確定其在雜湊環上的位置,這裡假設將上文中三台伺服器使用ip地址雜湊後在環空間的位置如下:

    接下來使用如下演算法定位元據訪問到相應伺服器:將資料key使用相同的函數H計算出雜湊值h,通根據h確定此資料在環上的位置,從此位置沿環順時針“行走”,第一台遇到的伺服器就是其應該定位到的伺服器。

例如我們有A、B、C、D四個資料對象,經過雜湊計算後,在環空間上的位置如下:

    根據一致性雜湊演算法,資料A會被定為到Server 1上,D被定為到Server 3上,而B、C分別被定為到Server 2上。

容錯性與可擴充性分析

    下面分析一致性雜湊演算法的容錯性和可擴充性。現假設Server 3宕機了:

可以看到此時A、C、B不會受到影響,只有D節點被重定位到Server 2。一般的,在一致性雜湊演算法中,如果一台伺服器不可用,則受影響的資料僅僅是此伺服器到其環空間中前一台伺服器(即順著逆時針方向行走遇到的第一台伺服器)之間資料,其它不會受到影響。

下面考慮另外一種情況,如果我們在系統中增加一台伺服器Memcached Server 4:

    此時A、D、C不受影響,只有B需要重定位到新的Server 4。一般的,在一致性雜湊演算法中,如果增加一台伺服器,則受影響的資料僅僅是新伺服器到其環空間中前一台伺服器(即順著逆時針方向行走遇到的第一台伺服器)之間資料,其它不會受到影響。

綜上所述,一致性雜湊演算法對於節點的增減都只需重定位環空間中的一小部分資料,具有較好的容錯性和可擴充性。

虛擬節點

    一致性雜湊演算法在服務節點太少時,容易因為節點分部不均勻而造成資料扭曲問題。例如我們的系統中有兩台伺服器,其環分布如下:

    此時必然造成大量資料集中到Server 1上,而只有極少量會定位到Server 2上。為瞭解決這種資料扭曲問題,一致性雜湊演算法引入了虛擬節點機制,即對每一個服務節點計算多個雜湊,每個計算結果位置都放置一個此服務節點,稱為虛擬節點。具體做法可以在伺服器ip或主機名稱的後面增加編號來實現。例如上面的情況,我們決定為每台伺服器計算三個虛擬節點,於是可以分別計算“Memcached Server 1#1”、“Memcached Server 1#2”、“Memcached
Server 1#3”、“Memcached Server 2#1”、“Memcached Server 2#2”、“Memcached Server 2#3”的雜湊值,於是形成六個虛擬節點:

    同時資料定位演算法不變,只是多了一步虛擬節點到實際節點的映射,例如定位到“Memcached Server 1#1”、“Memcached Server 1#2”、“Memcached Server 1#3”三個虛擬節點的資料均定位到Server 1上。這樣就解決了服務節點少時資料扭曲的問題。在實際應用中,通常將虛擬節點數設定為32甚至更大,因此即使很少的服務節點也能做到相對均勻的資料分布。

總結

    目前一致性雜湊基本成為了分布式系統組件的標準配置,例如Memcached的各種用戶端都提供內建的一致性雜湊支援。本文只是簡要介紹了這個演算法,更深入的內容可以參看論文《Consistent
Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》,同時提供一個C語言版本的實現供參考。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.