一致性哈希算法及其在分布式系統(tǒng)中的應用

轉(zhuǎn)載:http://blog.codinglabs.org/articles/consistent-hashing.html

摘要

本文將會從實際應用場景出發(fā),介紹一致性哈希算法(Consistent Hashing)及其在分布式系統(tǒng)中的應用傲须。首先本文會描述一個在日常開發(fā)中經(jīng)常會遇到的問題場景猎贴,借此介紹一致性哈希算法以及這個算法如何解決此問題宫屠;接下來會對這個算法進行相對詳細的描述黑低,并討論一些如虛擬節(jié)點等與此算法應用相關(guān)的話題鳍侣。

分布式緩存問題

假設我們有一個網(wǎng)站第股,最近發(fā)現(xiàn)隨著流量增加应民,服務器壓力越來越大,之前直接讀寫數(shù)據(jù)庫的方式不太給力了夕吻,于是我們想引入Memcached作為緩存機制』迩拢現(xiàn)在我們一共有三臺機器可以作為Memcached服務器,如下圖所示梭冠。

很顯然辕狰,最簡單的策略是將每一次Memcached請求隨機發(fā)送到一臺Memcached服務器,但是這種策略可能會帶來兩個問題:一是同一份數(shù)據(jù)可能被存在不同的機器上而造成數(shù)據(jù)冗余控漠,二是有可能某數(shù)據(jù)已經(jīng)被緩存但是訪問卻沒有命中蔓倍,因為無法保證對相同key的所有訪問都被發(fā)送到相同的服務器悬钳。因此,隨機策略無論是時間效率還是空間效率都非常不好偶翅。

要解決上述問題只需做到如下一點:保證對相同key的訪問會被發(fā)送到相同的服務器默勾。很多方法可以實現(xiàn)這一點,最常用的方法是計算哈希聚谁。例如對于每次訪問母剥,可以按如下算法計算其哈希值:

h = Hash(key) % 3

其中Hash是一個從字符串到正整數(shù)的哈希映射函數(shù)。這樣形导,如果我們將Memcached Server分別編號為0环疼、1、2朵耕,那么就可以根據(jù)上式和key計算出服務器編號h炫隶,然后去訪問。

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

h = Hash(key) % N

這個算式計算每個key的請求應該被發(fā)送到哪臺服務器处嫌,其中N為服務器的臺數(shù)栅贴,并且服務器按照0 – (N-1)編號。

這個算法的問題在于容錯性和擴展性不好熏迹。所謂容錯性是指當系統(tǒng)中某一個或幾個服務器變得不可用時檐薯,整個系統(tǒng)是否可以正確高效運行;而擴展性是指當加入新的服務器后癣缅,整個系統(tǒng)是否可以正確高效運行厨剪。

現(xiàn)假設有一臺服務器宕機了,那么為了填補空缺友存,要將宕機的服務器從編號列表中移除,后面的服務器按順序前移一位并將其編號值減一陶衅,此時每個key就要按h = Hash(key) % (N-1)重新計算屡立;同樣,如果新增了一臺服務器搀军,雖然原有服務器編號不用改變膨俐,但是要按h = Hash(key) % (N+1)重新計算哈希值。因此系統(tǒng)中一旦有服務器變更罩句,大量的key會被重定位到不同的服務器從而造成大量的緩存不命中焚刺。而這種情況在分布式系統(tǒng)中是非常糟糕的。

一個設計良好的分布式哈希方案應該具有良好的單調(diào)性门烂,即服務節(jié)點的增減不會造成大量哈希重定位乳愉。一致性哈希算法就是這樣一種哈希方案兄淫。

一致性哈希算法

算法簡述

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

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

下一步將各個服務器使用H進行一個哈希备闲,具體可以選擇服務器的ip或主機名作為關(guān)鍵字進行哈希晌端,這樣每臺機器就能確定其在哈希環(huán)上的位置,這里假設將上文中三臺服務器使用ip地址哈希后在環(huán)空間的位置如下:

接下來使用如下算法定位數(shù)據(jù)訪問到相應服務器:將數(shù)據(jù)key使用相同的函數(shù)H計算出哈希值h恬砂,通根據(jù)h確定此數(shù)據(jù)在環(huán)上的位置斩松,從此位置沿環(huán)順時針“行走”,第一臺遇到的服務器就是其應該定位到的服務器觉既。

例如我們有A惧盹、B、C瞪讼、D四個數(shù)據(jù)對象钧椰,經(jīng)過哈希計算后,在環(huán)空間上的位置如下:

根據(jù)一致性哈希算法符欠,數(shù)據(jù)A會被定為到Server 1上嫡霞,D被定為到Server 3上,而B希柿、C分別被定為到Server 2上诊沪。

容錯性與可擴展性分析

下面分析一致性哈希算法的容錯性和可擴展性。現(xiàn)假設Server 3宕機了:

可以看到此時A曾撤、C端姚、B不會受到影響,只有D節(jié)點被重定位到Server 2挤悉。一般的渐裸,在一致性哈希算法中,如果一臺服務器不可用装悲,則受影響的數(shù)據(jù)僅僅是此服務器到其環(huán)空間中前一臺服務器(即順著逆時針方向行走遇到的第一臺服務器)之間數(shù)據(jù)刚夺,其它不會受到影響锣险。

下面考慮另外一種情況,如果我們在系統(tǒng)中增加一臺服務器Memcached Server 4:

此時A、D醉蚁、C不受影響蕾殴,只有B需要重定位到新的Server 4员舵。一般的,在一致性哈希算法中讯柔,如果增加一臺服務器,則受影響的數(shù)據(jù)僅僅是新服務器到其環(huán)空間中前一臺服務器(即順著逆時針方向行走遇到的第一臺服務器)之間數(shù)據(jù)宪巨,其它不會受到影響磷杏。

綜上所述,一致性哈希算法對于節(jié)點的增減都只需重定位環(huán)空間中的一小部分數(shù)據(jù)捏卓,具有較好的容錯性和可擴展性极祸。

虛擬節(jié)點

一致性哈希算法在服務節(jié)點太少時,容易因為節(jié)點分部不均勻而造成數(shù)據(jù)傾斜問題怠晴。例如我們的系統(tǒng)中有兩臺服務器遥金,其環(huán)分布如下:

此時必然造成大量數(shù)據(jù)集中到Server 1上,而只有極少量會定位到Server 2上蒜田。為了解決這種數(shù)據(jù)傾斜問題稿械,一致性哈希算法引入了虛擬節(jié)點機制,即對每一個服務節(jié)點計算多個哈希冲粤,每個計算結(jié)果位置都放置一個此服務節(jié)點美莫,稱為虛擬節(jié)點。具體做法可以在服務器ip或主機名的后面增加編號來實現(xiàn)梯捕。例如上面的情況厢呵,我們決定為每臺服務器計算三個虛擬節(jié)點,于是可以分別計算“Memcached Server 1#1”傀顾、“Memcached Server 1#2”襟铭、“Memcached Server 1#3”、“Memcached Server 2#1”短曾、“Memcached Server 2#2”寒砖、“Memcached Server 2#3”的哈希值,于是形成六個虛擬節(jié)點:

同時數(shù)據(jù)定位算法不變嫉拐,只是多了一步虛擬節(jié)點到實際節(jié)點的映射哩都,例如定位到“Memcached Server 1#1”、“Memcached Server 1#2”椭岩、“Memcached Server 1#3”三個虛擬節(jié)點的數(shù)據(jù)均定位到Server 1上茅逮。這樣就解決了服務節(jié)點少時數(shù)據(jù)傾斜的問題。在實際應用中判哥,通常將虛擬節(jié)點數(shù)設置為32甚至更大,因此即使很少的服務節(jié)點也能做到相對均勻的數(shù)據(jù)分布碉考。

總結(jié)

目前一致性哈纤疲基本成為了分布式系統(tǒng)組件的標準配置,例如Memcached的各種客戶端都提供內(nèi)置的一致性哈希支持侯谁。本文只是簡要介紹了這個算法锌仅,更深入的內(nèi)容可以參看論文《Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》章钾,同時提供一個C語言版本的實現(xiàn)供參考。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末热芹,一起剝皮案震驚了整個濱河市贱傀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伊脓,老刑警劉巖府寒,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異报腔,居然都是意外死亡株搔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門纯蛾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纤房,“玉大人,你說我怎么就攤上這事翻诉∨谝蹋” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵碰煌,是天一觀的道長舒岸。 經(jīng)常有香客問我,道長拄查,這世上最難降的妖魔是什么吁津? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮堕扶,結(jié)果婚禮上碍脏,老公的妹妹穿的比我還像新娘。我一直安慰自己稍算,他們只是感情好典尾,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糊探,像睡著了一般钾埂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上科平,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天褥紫,我揣著相機與錄音,去河邊找鬼瞪慧。 笑死髓考,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的弃酌。 我是一名探鬼主播氨菇,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼儡炼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了查蓉?” 一聲冷哼從身側(cè)響起乌询,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豌研,沒想到半個月后妹田,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡聂沙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年秆麸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片及汉。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡沮趣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坷随,到底是詐尸還是另有隱情房铭,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布温眉,位于F島的核電站缸匪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏类溢。R本人自食惡果不足惜凌蔬,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闯冷。 院中可真熱鬧砂心,春花似錦、人聲如沸蛇耀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纺涤。三九已至译暂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撩炊,已是汗流浹背外永。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拧咳,地道東北人象迎。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像呛踊,于是被迫代替她去往敵國和親砾淌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容