淺談-一致性哈希算法

更多文章,請關(guān)注我的個人博客:www.ahey.net

引言

哈希算法因妇,多應(yīng)用于多數(shù)框架的底層實現(xiàn)董朝,在JAVA中與其相關(guān)的有HashMap、HashTable等。

首先拋幾個問題

  • 都知道Hashmap底層使用了hash(取模)算法辅甥,它與一致性hash算法有什么區(qū)別呢酝润?
  • 在分布式緩存中,hash算法起了很大的作用璃弄,它也是上述提到的取模算法嗎要销?
  • 取模法與一致性哈希算法有什么區(qū)別?

什么是哈希算法

hash即散列夏块,哈希算法又稱散列算法疏咐,將任意長度的二進(jìn)制值映射為較短的固定長度的二進(jìn)制值(哈希值),哈希值是一段數(shù)據(jù)唯一且極其緊湊的數(shù)值表示形式脐供,常用于快速查找和加密算法浑塞。

傳統(tǒng)取模法(以Hashmap為例)

HashMap底層結(jié)構(gòu)是數(shù)組+鏈表+紅黑樹。數(shù)組相當(dāng)于一個bucket政己,在bucket這一層就用到了取模法酌壕。

假設(shè)數(shù)組的長度為n,當(dāng)一個Node(key-value)加入時歇由,先計算key的hash值仅孩,再通過 (n -1)& hash 的位操作,得到bucket的下標(biāo)印蓖。這里的位操作其實就是取模算法 hash % n的優(yōu)化版辽慕。這時候問題來了,由于數(shù)組容量必定有限赦肃,當(dāng)需要擴(kuò)容(新增Node節(jié)點)時溅蛉,Hashmap會rehash(重建hash表),可想而知重建會導(dǎo)致大量的key需要遷移并重新計算下標(biāo)他宛。 故Hashmap源碼中提到了要合理設(shè)置初始長度和負(fù)載因子船侧,以“內(nèi)存換性能”的操作來避免rehash。

取模思路如下
假設(shè)數(shù)組初始長度n = 5厅各,增加結(jié)點至n = 6镜撩,最終導(dǎo)致全部數(shù)據(jù)都需進(jìn)行遷移,改變下標(biāo)队塘。

20200731152435758_1941699246.jpg

換個角度思考袁梗,是否可以做到,在擴(kuò)容的時候盡最大化地減少遷移的操作憔古,并且保證原來的key仍在原來的位置(在分布式緩存系統(tǒng)中遮怜,這點尤為重要,否則容易引起緩存雪崩等情況)

一致性哈希算法

引自wiki
一致哈希 是一種特殊的哈希算法鸿市。在使用一致哈希算法后锯梁,哈希表槽位數(shù)(大屑赐搿)的改變平均只需要對K/n 個關(guān)鍵字重新映射,其中K是關(guān)鍵字的數(shù)量陌凳,n是槽位數(shù)量剥懒。然而在傳統(tǒng)的哈希表中,添加或刪除一個槽位的幾乎需要對所有關(guān)鍵字進(jìn)行重新映射合敦。

其實一致性哈希算法也是一種取模法初橘,只不過不直接對服務(wù)器數(shù)量進(jìn)行取模分發(fā),而是對2^32進(jìn)行取模蛤肌,以此解決重新散列的問題壁却。

實現(xiàn)原理大致如下

  • 構(gòu)造由2^32個點位組成的環(huán)形hash空間

  • 將服務(wù)器節(jié)點映射到hash空間

  • 將存儲對象映射到hash空間

  • 將對象沿順時針轉(zhuǎn)動批狱,碰到的第一個服務(wù)器節(jié)點裸准,即當(dāng)前對象應(yīng)緩存的節(jié)點

將上述原理概括成描述一致性哈希算法的規(guī)則:環(huán)形空間,節(jié)點映射赔硫,對象映射炒俱,順時針相遇

它目前已經(jīng)應(yīng)用于AWS Dynamodb高可用 Nosql數(shù)據(jù)庫Memcached分布式緩存爪膊、Nginx負(fù)載均衡等

一致性哈先ㄎ颍基于分布式緩存的應(yīng)用

為什么說一致性哈希是一種特殊的哈希算法,可以借助分布式緩存的例子來說明推盛。

假設(shè)現(xiàn)在有三個服務(wù)器節(jié)點A峦阁、B、C耘成,三條待緩存的鍵值對數(shù)據(jù)a榔昔、b、c瘪菌。

初始節(jié)點

  • 將三個服務(wù)器節(jié)點通過hash(ip地址) % 2^32 取模得到一個整數(shù)值(介于0 ~ 2^32)撒会,定位到環(huán)形空間上
20200731163639418_10607236.jpg
  • 將三個緩存對象通過hash(key) % 2^32 取模得到一個整數(shù)值(介于0 ~ 2^32),定位到環(huán)形空間上
20200731171432756_1761578491.png
  • 將緩存對象沿順時針“轉(zhuǎn)動”师妙,當(dāng)?shù)谝粋€遇到的服務(wù)器節(jié)點诵肛,就是緩存對象對應(yīng)存儲的節(jié)點

如下圖所示,緩存對象a在服務(wù)節(jié)點A上存儲默穴,緩存對象b在服務(wù)節(jié)點B上存儲...

20200731180418926_624189149.png

節(jié)點故障

  • 假設(shè)此時節(jié)點B出現(xiàn)故障下線了怔檩,按照一致性哈希的規(guī)則中的“順時針相遇”,緩存對象b應(yīng)該與服務(wù)節(jié)點C相遇蓄诽,存儲位置變動珠洗,而其他節(jié)點按兵不動,不受影響
20200731180042941_566711142.png

新增節(jié)點

  • 假設(shè)此時新增一個節(jié)點D若专,位于A與C之間许蓖,如下圖,按照一致性哈希的規(guī)則中的“順時針相遇”可知,所有緩存對象無需再次轉(zhuǎn)動
20200731180751711_289411648.png
  • 假設(shè)此時新增一個節(jié)點E膊爪,位于A與B之間自阱,如下圖,按照一致性哈希的規(guī)則中的“順時針相遇”可知米酬,緩存對象b與服務(wù)節(jié)點E相遇沛豌,存儲位置變動
20200731181540803_91107481.png

hash環(huán)傾斜

在描述基于分布式緩存的應(yīng)用時,看似一切都很理想化赃额。
但是會遇到一種情況加派,實際服務(wù)節(jié)點的映射位置可能比較極端,進(jìn)而造成數(shù)據(jù)傾斜跳芳,這種情況會導(dǎo)致大多數(shù)的緩存對象都集中在一個節(jié)點芍锦,失去了哈希算法存在的意義。

20200731182843005_87592856.png

虛擬節(jié)點

hash算法無法保證絕對的平衡飞盆,一致性哈希算法容易導(dǎo)致數(shù)據(jù)傾斜娄琉,故它又引入了“虛擬節(jié)點”,即實際節(jié)點在hash空間的復(fù)制節(jié)點吓歇,兩者關(guān)系為1:n孽水,虛擬節(jié)點在hash空間中以hash值排列

總結(jié)

一致性哈希算法,相較于常規(guī)的取模法城看,解決了增刪節(jié)點導(dǎo)致的重新散列的問題女气,基于“環(huán)形空間,節(jié)點映射测柠,對象映射炼鞠,順時針相遇”的規(guī)則,加上虛擬節(jié)點的引入鹃愤,很大程度地解決了分布式系統(tǒng)的心結(jié)簇搅,故它常用于Nginx負(fù)載均衡、Dynamodb分布式數(shù)據(jù)庫等软吐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘩将,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凹耙,更是在濱河造成了極大的恐慌姿现,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肖抱,死亡現(xiàn)場離奇詭異备典,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)意述,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門闷旧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人广凸,你說我怎么就攤上這事〕闭耄” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵倚喂,是天一觀的道長每篷。 經(jīng)常有香客問我,道長端圈,這世上最難降的妖魔是什么焦读? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮舱权,結(jié)果婚禮上矗晃,老公的妹妹穿的比我還像新娘。我一直安慰自己刑巧,他們只是感情好喧兄,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布无畔。 她就那樣靜靜地躺著啊楚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浑彰。 梳的紋絲不亂的頭發(fā)上恭理,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音郭变,去河邊找鬼颜价。 笑死,一個胖子當(dāng)著我的面吹牛诉濒,可吹牛的內(nèi)容都是我干的周伦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼未荒,長吁一口氣:“原來是場噩夢啊……” “哼专挪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起片排,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤寨腔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后率寡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迫卢,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年冶共,在試婚紗的時候發(fā)現(xiàn)自己被綠了乾蛤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片每界。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖家卖,靈堂內(nèi)的尸體忽然破棺而出盆犁,到底是詐尸還是另有隱情,我是刑警寧澤篡九,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布谐岁,位于F島的核電站,受9級特大地震影響榛臼,放射性物質(zhì)發(fā)生泄漏伊佃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一沛善、第九天 我趴在偏房一處隱蔽的房頂上張望航揉。 院中可真熱鬧,春花似錦金刁、人聲如沸帅涂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媳友。三九已至,卻和暖如春产捞,著一層夾襖步出監(jiān)牢的瞬間醇锚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工坯临, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留焊唬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓看靠,卻偏偏與公主長得像赶促,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挟炬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355