色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

JAVA面試又被問一致性hash算法,到底啥是一致性hash?

呂致盈2年前16瀏覽0評論

用最通俗易懂的方式來解釋下一致性hash算法;

首先我們要明確的是一般的hash算法在取模的時候往往跟實際應用有關!

比如說nginxhash的時候,會根據后臺的應用服務器數量進行取模,比如說后臺有四臺應用,那么hash(key)%4=(0,1,2,3),就能獲取到具體哪一臺的標號,這個時候如果后臺應用需要擴容,那么hash算法就要換成hash(key)%6=(0,1,2,3,4,5),分布到六臺不同的機器上去請求,看著沒什么太大問題,但是如果我們把場景切換為數據庫根據業務主鍵business_no進行hash的的分庫分表結構,在切換之后,因為hash算法的改變,原本的數據落在4,但是hash結果為5,肯定查不到原來的數據,這就出現了數據查詢錯誤問題!

而如果上述問題是出現在redis上,因為數據大量不命中,大量的查詢降落在底層的數據庫上,嚴重的話發生緩存雪崩問題,導致數據庫系統乃至整個系統全部雪崩;

下面詳細說下一致性hash算法(以redis存儲為例),來解決上面遇到的問題:

一致性hash算法,不管你的應用有多少,都使用2^32(2的32次方)作為取模,并且將0和2^32-1首尾相連,結成一個環,這樣所有使用一致性hash算法的數據都大概率均勻的落在這個環上;

落在環上面的數據又是怎么落到不同的redis服務器上的呢?我們不管是使用redis服務器的IP也好,域名也好,總之是一個唯一標識,通過計算hash值也落在這個環上(ABCD服務器節點),然后規定把落在環上的數據以順時針的方向旋轉,保存在遇到的第一個節點(服務器)上,這很好理解;如下圖所示:

使用了一致性hash之后,我們服務器的擴展也會變得很容易,如果監控到某個節點(D)壓力比較大,則通過計算hash值,在這個節點的逆時針上游加一個服務器E(A和D之間),如下圖:


這時候如果有請求進來,在整個環上的數據,只有A到E之間的數據獲取不到從而對下層數據庫有影響,而其他的所有數據不會有任何影響,由此可見使用一致性hash擴展是十分方便的!

一致性hash存在的問題:

1,雪崩效應:假設我們并沒有上面說的類似的監控,或者某個節點(B)的數據激增,在我們的反應之前,這個時候這個節點出現了宕機,那么所有的數據請求將迅速落在A上,A不僅承受自己的數據,還要承受B的,肯定也馬上奔潰,最終整個緩存系統發生緩存雪崩效應!

2,分布不均勻:上面的例子對于hash算法過于理想化了,比如ABCD四臺服務器的hash值剛好為1,2,3,4也就代表著hash值在(4,2^32-1]這個范圍的所有數據將落在一臺服務上,這也將是災難性的。。。

那么我們怎么解決這種數據分布十分不均勻的情況呢?

解決辦法:最好的辦法就是增加虛擬節點,截圖如下:

ABCD對每個服務器A,B,C,D都新增了一個(也可以是多個)虛擬節點,也就是說現在A節點可以接受B2-A1加上C1到A2的數據,假設A服務宕機了,那么A1的數據將落在C2(也就是C),A2的數據將落在D1(也就是D)上,也就是說隨著崩潰的服務器增多,相對應的數據將分散在更多的服務器,從而防止整個緩存系統的持續雪崩效應;

經過上述的案例,我們能看到一致性hash遵循的原則有下列幾個:①,平衡性:數據將盡可能的均勻分布在整個hash環上,

②,單調性:在擴展的時候,將保證原來的數據盡量少的落在新的節點上。

③,分散性:相同的內容盡量避免落在不同的節點上去!

一致性hash原理很簡單,但是一致性hash算法廣泛的用在了諸如redis集群,數據庫分庫分表等情景當中,良好解決了數據分布不均,擴展困難的難題,是大規模集群中的優良算法!

個人感覺本文中的解釋還算通俗易懂,如果有不明白的朋友,可以私信我,我再解釋下,后期會有更多的技術分享,也請持續關注,謝謝。。。