一致性Hash算法

一、Redis集羣的使用

對於大型系統,當數據量很大時,需要對數據庫進行分庫分表。當數據量很大時,Redis同樣要進行此操作,就是分庫分表。假設經過分庫分表,現在有4臺Redis服務器,當查詢一條數據的時候,此時不知道具體在哪一個服務器上,可以用Hash算法。對請求鍵求Hash值,公式爲hash(a.png)%4=2。可知我們定位到了第2號服務器。這樣就不需要遍歷所有服務器,提高了性能。

二、使用Hash的問題

上述方式雖然提升了一些性能,我們不需要對所有的服務器進行遍歷。但是也存在着一些問題。當一臺服務器出現問題時,我們需要移除它,選擇就只剩下三臺服務器了。此時,利用公式  hash(a.png)%3=1 ,可是數據不在第一天服務器而是在第二臺服務器。這是所有緩存失效,用戶直接向數據庫請求數據,會造成緩存雪崩。

三、一致性哈希算法

通過一致性hash算法,我們可以讓影響降到最小。不出現緩存雪崩的情況。

一致性hash算法也是取模的方法,但不是剛纔說的對服務器的數量取模,而是對2^32取模。一致性hash算法將整個hash值空間組織成一個虛擬的圓環。圓環的正上方的點代表0,0點右側代表1,2,3,4.。。。依次類推,知道2^32-1。我們把由2^32個點組成的圓環稱爲hash環。

下一步將各個服務器使用hash進行一個哈希,具體可以選擇服務器的IP或主機名作爲關鍵字進行hash。這樣就確定了每臺機器在哈希環上的位置。這裏假設將上文中四臺服務器使用IP地址哈希後在環中的位置如下。

è¿éåå¾çæè¿°

將數據key使用相同的hash函數計算出哈希值,並確定此數據在環上的位置。從此位置沿環順時針行走,第一臺遇到的服務器就是其應該定位到的服務器。

四、一致性hash算法的容錯性和可擴展性

如果NodeC()不幸宕機,可以此時A,B,D不會受到影響,只有C對象被重新定位到NodeD()。一般的,在一致性hash算法中,如果一臺服務器不可用,則受影響的僅僅是此服務器向前一臺的服務器,其他服務器不會受到影響。

一致性hash算法對於節點的增減都只需重定位環空間中的一小部分數據,具有較好的容錯性和可擴展性。

五、Hash環的數據傾斜問題

一致性hash算法在服務器節點太少時,容易因爲節點分佈不均勻造成數據傾斜(被緩衝的對象大部分集中緩存在一臺服務器上)。爲了解決數據傾斜問題,一致性hash算法引入了虛擬節點機制。對於每一個服務器計算多個hash,每個計算位置都放置一個服務節點,稱爲虛擬節點。同一個服務器計算出來的虛擬節點仍訪問此服務器。這樣就解決了服務器節點太少時容易因爲節點分佈不均勻造成數據傾斜。

參考文章:https://blog.csdn.net/xlgen157387/article/details/79544524

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章