一致性Hash(Hash環)

2021-08-17 15:49:02 字數 1495 閱讀 4131

當前,memcached、redis這類分布式kv快取已經非常普遍。從本篇開始,本系列將分析分布式快取相關的原理、使用策略和最佳實踐。

我們知道memcached的分布式其實是一種「偽分布式」,也就是它的伺服器結點之間其實是相互無關聯的,之間沒有網路拓撲關係,由客戶端來決定乙個key是存放到哪台機器。

具體來講,假設我有多台memcached伺服器,編號分別為m0,m1,m2,…。對於乙個key,由客戶端來決定存放到哪台機器,那最簡單的hash公式就是 key % n,其中n是機器的總數。

但這有個問題,一旦機器數變少,或者增加機器,n發生變化,那之前存放的資料就全部無效了。因為你按照新的n值取模計算出的機器編號,和當時按舊的n值取模算出的機器編號肯定是不等的,也就意味著絕大部分快取會失效。

這個問題的解決辦法就是用1種特別的hash函式,盡可能使得,增加機器/減少機器時,快取失效的數目降到最低,這就是hash環,或者叫一致性hash。

上面說的hash函式,只經過了1次hash,即把key hash到對應的機器編號。 

而hash環有2次hash: 

(1)把所有機器編號hash到這個環上 

(2)把key也hash到這個環上。然後在這個環上進行匹配,看這個key和哪台機器匹配。

具體來講,如下:

假定有這樣乙個hash函式,其值空間為(0到2的32次方-1) ,也就是說,其hash值是個32位無整型數字 ,這些數字組成乙個環。

然後,先對機器進行hash(比如根據機器的ip),算出每台機器在這個環上的位置; 再對key進行hash,算出該key在環上的位置,然後從這個位置往前走,遇到的第一台機器就是該key對應的機器,就把該(key, value) 儲存到該機器上。

首先計算出每台cache伺服器在環上的位置(圖中的大圓圈);然後每來乙個(key, value),計算出在環上的位置(圖中的小圓圈),然後順時針走,遇到的第1個機器,就是其要儲存的機器。

這裡的關鍵點是:當你增加/減少機器時,其他機器在環上的位置並不會發生改變。這樣只有增加的那台機器、或者減少的那台機器附近的資料會失效,其他機器上的資料都還是有效的。

當你機器不多的時候,很可能出現幾台機器在環上面貼的很近,不是在環上均勻分布。這將會導致大部分資料,都會集中在某1臺機器上。

為了解決這個問題,可以引入「虛擬機器」的概念,也就是說:1臺機器,我在環上面計算出多個位置。怎麼弄呢? 假設用機器的ip來hash,我可以在ip後面加上幾個編號, ip_1, ip_2, ip_3, .. 把1臺物理機器生個多個虛擬機器的編號。

資料首先對映到「虛擬機器上」,再從「虛擬機器」對映到物理機器上。因為虛擬機器可以很多,在環上面均勻分布,從而保證資料均勻分布到物理機器上面。

上面我們提到了伺服器的機器增加、減少,問題是客戶端怎麼知道呢?

一種笨辦法就是手動的,當伺服器機器增加、減少時候,重新配置客戶端,重啟客戶端。

另外一種,就是引入zk,伺服器的節點列表註冊到zk上面,客戶端監聽zk。發現結點數發生變化,自動更新自己的配置。

當然,不用zk,用乙個其他的中心結點,只要能實現這種更改的通知,也是可以的。

一致性雜湊環

大神的分享,我寫下自己的一些理解 首先,思考乙個問題 你有乙個億級訪問量的 每天每小時每分鐘有大量的資料在傳輸,存讀資料庫非常頻繁,伺服器的壓力很大。然後我們的解決方案是什麼 快取,memcache,redis。那麼,問題來了,你有10臺快取伺服器,想象一下 一條資料來了要寫,寫到哪台伺服器上去 乙...

強一致性 弱一致性 最終一致性

這種方式在es等分布式系統中也有體現,可以設定主shard提交即返回成功,或者需要replica shard提交成功再返回。提到分布式架構就一定繞不開 一致性 問題,而 一致性 其實又包含了資料一致性和事務一致性兩種情況,本文主要討論資料一致性 事務一致性指acid 複製是導致出現資料一致性問題的唯...

Hash環 一致性Hash原理

當前,memcached redis這類分布式kv快取已經非常普遍。從本篇開始,本系列將分析分布式快取相關的原理 使用策略和最佳實踐。我們知道memcached的分布式其實是一種 偽分布式 也就是它的伺服器結點之間其實是相互無關聯的,之間沒有網路拓撲關係,由客戶端來決定乙個key是存放到哪台機器。具...