成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

詳解Java分布式系統中一致性哈希算法

瀏覽:84日期:2022-08-13 18:47:05
業務場景

近年來B2C、O2O等商業概念的提出和移動端的發展,使得分布式系統流行了起來。分布式系統相對于單系統,解決了流量大、系統高可用和高容錯等問題。功能強大也意味著實現起來需要更多技術的支持。例如系統訪問層的負載均衡,緩存層的多實例主從復制備份,數據層的分庫分表等。

我們以負載均衡為例,常見的負載均衡方法有很多,但是它們的優缺點也都很明顯:

隨機訪問策略。系統隨機訪問,缺點:可能造成服務器負載壓力不均衡,俗話講就是撐的撐死,餓的餓死。 輪詢策略。請求均勻分配,如果服務器有性能差異,則無法實現性能好的服務器能夠多承擔一部分。 權重輪詢策略。權值需要靜態配置,無法自動調節,不適合對長連接和命中率有要求的場景。 Hash取模策略。不穩定,如果列表中某臺服務器宕機,則會導致路由算法產生變化,由此導致命中率的急劇下降。 一致性哈希策略。

以上幾個策略,排除本篇介紹的一致性哈希,可能使用最多的就是 Hash取模策略了。Hash取模策略的缺點也是很明顯的,這種缺點也許在負載均衡的時候不是很明顯,但是在涉及數據訪問的主從備份和分庫分表中就體現明顯了。

使用Hash取模的問題1.負載均衡

負載均衡時,假設現有3臺服務器(編號分別為0、1、2),使用哈希取模的計算方式則是:對訪問者的IP,通過固定算式hash(IP) % N(N為服務器的個數),使得每個IP都可以定位到特定的服務器。

例如現有IP地址 10.58.34.31,對IP哈希取模策時,計算結果為2,即訪問編號為2的服務器:

String ip = '10.58.34.31';int v1 = hash(ip) % 3;System.out.println('訪問服務器:' + v1);// 訪問服務器:2

如果此時服務器2宕機了,則會導致所有計算結果為2的 IP 對應的用戶都訪問異常(包括上例中的IP)。或者你新增了一臺服務器3,這時不修改N值的話那么服務器3永遠不會被訪問到。

詳解Java分布式系統中一致性哈希算法

當然如果你能動態獲取到當前可用服務器的個數,亦即N值是根據當前可用服務器個數動態來變化的,則可解決此問題。但是對于類似要在特定地區或特定IP來訪問特定服務器的這種需求就會造成訪問偏差。

2.分庫分表

負載均衡中有這種問題,那么分庫分表中同樣也有這樣的問題。例如隨著業務的飛速增長,我們的注冊用戶也越來越多,單個用戶表數量已經達到千萬級甚至更大。由于Mysql的單表建議百萬級數據存儲,所以這時為了保證系統查詢和運行效率,肯定會考慮到分庫分表。

對于分庫分表,數據的分配是個重要的問題,你需要保證數據分配在這個服務器,那么在查詢時也需要到該服務器上來查詢,否則會造成數據查詢丟失的問題。

通常是根據用戶的 ID 哈希取模得到的值然后路由到對應的存儲位置,計算公式為:hash(userId) % N,其中N為分庫或分表的個數。

例如分庫數為2時,計算結果為1,則ID為1010的用戶存儲在編號為1對應的庫中:

String userId = '1010';int v1 = hash(userId) % 2;System.out.println('存儲:' + v1);// 存儲:1

詳解Java分布式系統中一致性哈希算法

之后業務數量持續增長,又新增一臺用戶服務庫,當我們根據ID=1010去查詢數據時,路由計算方式為:

int v2 = hash(userId) % 3;System.out.println('存儲:' + v2);// 存儲:0

我們得到的路由值是0,最后的結果就不用說了,存在編號1上的數據我們去編號為0的庫上去查詢肯定是得不到查詢結果的。

詳解Java分布式系統中一致性哈希算法

為了數據可用,你需要做數據遷移,按照新的路由規則對所有用戶重新分配存儲地址。每次的庫或表的數量改變你都需要做一次全部用戶信息數據的遷移。不用想這其中的工作量是有多費時費力了。

是否有某種方法,有效解決這種分布式存儲結構下動態增加或刪除節點所帶來的問題,能保證這種不受實例數量變化影響而準確路由到正確的實例上的算法或實現機制呢?解決這些問題,一致性哈希算法誕生了。

基本思想原理

一致性哈希算法在1997年由麻省理工學院的Karger等人在解決分布式Cache中提出的,設計目標是為了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性哈希修正了CARP使用的簡單哈希算法帶來的問題,使得DHT可以在P2P環境中真正得到應用。

上面說的哈希取模方法,它是針對一個點的,業務布局嚴重依賴于這個計算的點值結果。你結算的結果是2,那么就對應到編號為2的服務器上。這樣的映射就造成了業務容錯性和可擴展性極低。

我們思考下,是否可以將這個計算結果的點值賦予范圍的意義?我們知道Hash取模之后得到的是一個 int 型的整值。

//Objects 類中默認的 hash 方法 public static int hash(Object... values) { return Arrays.hashCode(values);}

既然 hash的計算結果是 int 類型,而 java 中 int 的最小值是-2^31,最大值是2^31-1。意味著任何通過哈希取模之后的無符號值都會在 0 ~ 2^31-1范圍之間,共2^32個數。那我們是否可以不對服務器的數量進行取模而是直接對2^32取模。這就形成了一致性哈希的基本算法思想,什么意思呢?

這里需要注意一點:

默認的 hash 方法結果是有負值的情況,因此需要我們重寫hash方法,保證哈希值的非負性。

簡單來說,一致性Hash算法將整個哈希值空間組織成一個虛擬的圓環,如假設某哈希函數 H 的值空間為 0 ~ 2^32-1(即哈希值是一個32位無符號整形),整個哈希環如下:

詳解Java分布式系統中一致性哈希算法

整個空間圓按順時針方向布局,圓環的正上方的點代表0,0點右側的第一個點代表1。以此類推2、3、4、5、6……直到232-1,也就是說0點左側的第一個點代表232-1, 0和2^32-1在零點中方向重合,我們把這個由2^32個點組成的圓環稱為 Hash環。

那么,一致性哈希算法與上圖中的圓環有什么關系呢?仍然以之前描述的場景為例,假設我們有4臺服務器,服務器0、服務器1、服務器2,服務器3,那么,在生產環境中,這4臺服務器肯定有自己的 IP 地址或主機名,我們使用它們各自的 IP 地址或主機名作為關鍵字進行哈希計算,使用哈希后的結果對2^32取模,可以使用如下公式示意:

hash(服務器的IP地址) % 2^32

最后會得到一個 [0, 2^32-1]之間的一個無符號整形數,這個整數就代表服務器的編號。同時這個整數肯定處于[0, 2^32-1]之間,那么,上圖中的 hash 環上必定有一個點與這個整數對應。那么這個服務器就可以映射到這個環上。

多個服務器都通過這種方式進行計算,最后都會各自映射到圓環上的某個點,這樣每臺機器就能確定其在哈希環上的位置,如下圖所示。

詳解Java分布式系統中一致性哈希算法

如何提高容錯性和擴展性的

那么用戶訪問,如何分配訪問的服務器呢?我們根據用戶的 IP 使用上面相同的函數 Hash 計算出哈希值,并確定此數據在環上的位置,從此位置沿環 順時針行走,遇到的第一臺服務器就是其應該定位到的服務器。

詳解Java分布式系統中一致性哈希算法

從上圖可以看出 用戶1 順時針遇到的第一臺服務器是 服務器3 ,所以該用戶被分配給服務器3來提供服務。同理可以看出用戶2被分配給了服務器2。

1. 新增服務器節點

如果這時需要新增一臺服務器節點,一致性哈希策略是如何應對的呢?如下圖所示,我們新增了一臺服務器4,通過上述一致性哈希算法計算后得出它在哈希環的位置。

詳解Java分布式系統中一致性哈希算法

可以發現,原來訪問服務器3的用戶1現在訪問的對象是服務器4,用戶能正常訪問且服務不需要停機就可以自動切換。

2. 刪除服務器節點

如果這時某臺服務器異常宕機或者運維撤銷了一臺服務器,那么這時會發生什么情況呢?如下圖所示,假設我們撤銷了服務器2。

詳解Java分布式系統中一致性哈希算法

可以看出,我們服務仍然能正常提供服務,只不過這時用戶2會被分配到服務1上了而已。

通過一致性哈希的方式,我們提高了我們系統的容錯性和可擴展性,分布式節點的變動不會影響整個系統的運行且不需要我們做一些人為的調整策略。

Hash環的數據傾斜問題

一致性哈希雖然為我們提供了穩定的切換策略,但是它也有一些小缺陷。因為 hash取模算法得到的結果是隨機的,我們并不能保證各個服務節點能均勻的分配到哈希環上。

例如當有4個服務節點時,我們把哈希環認為是一個圓盤時鐘,我們并不能保證4個服務節點剛好均勻的落在時鐘的 12、3、6、9點上。

分布不均勻就會產生一個問題,用戶的請求訪問就會不均勻,同時4個服務承受的壓力就會不均勻。這種問題現象我們稱之為,Hash環的數據傾斜問題。

詳解Java分布式系統中一致性哈希算法

如上圖所示,服務器0 到 服務器1 之間的哈希點值占據比例最大,大量請求會集中到 服務器1 上,而只有極少量會定位到 服務器0 或其他幾個節點上,從而出現 hash環偏斜的情況。

如果想要均衡的將緩存分布到每臺服務器上,最好能讓這每臺服務器盡量多的、均勻的出現在hash環上,但是如上圖中所示,真實的服務器資源只有4臺,我們怎樣憑空的讓它們多起來呢?

既然沒有多余的真正的物理服務器節點,我們就只能將現有的物理節點通過虛擬的方法復制出來。

這些由實際節點虛擬復制而來的節點被稱為 '虛擬節點',即對每一個服務節點計算多個哈希,每個計算結果位置都放置一個此服務節點,稱為虛擬節點。具體做法可以在服務器IP或主機名的后面增加編號來實現。

如上圖所示,假如 服務器1 的 IP 是 192.168.32.132,那么原 服務器1 節點在環形空間的位置就是hash('192.168.32.132') % 2^32。

我們基于 服務器1 構建兩個虛擬節點,Server1-A 和 Server1-B,虛擬節點在環形空間的位置可以利用(IP+后綴)計算,例如:

hash('192.168.32.132#A') % 2^32hash('192.168.32.132#B') % 2^32

此時,環形空間中不再有物理節點 服務器1,服務器2,……,替代的是只有虛擬節點 Server1-A,Server1-B,Server2-A,Server2-B,……。

詳解Java分布式系統中一致性哈希算法

同時數據定位算法不變,只是多了一步虛擬節點到實際節點的映射,例如定位到 “Server1-A”、“Server1-B” 兩個虛擬節點的數據均定位到 服務器1上。這樣就解決了服務節點少時數據傾斜的問題。

在實際應用中,通常將虛擬節點數設置為32甚至更大,因此即使很少的服務節點也能做到相對均勻的數據分布。由于虛擬節點數量較多,與虛擬節點的映射關系也變得相對均衡了。

總結

一致性哈希一般在分布式緩存中使用的也比較多,本篇只介紹了服務的負載均衡和分布式存儲,對于分布式緩存其實原理是類似的,讀者可以自己舉一反三來思考下。

其實,在分布式存儲和分布式緩存中,當服務節點發生變化時(新增或減少),一致性哈希算法并不能杜絕數據遷移的問題,但是可以有效避免數據的全量遷移,需要遷移的只是更改的節點和它的上游節點它們兩個節點之間的那部分數據。

另外,我們都知道 hash算法 有一個避免不了的問題,就是哈希沖突。對于用戶請求IP的哈希沖突,其實只是不同用戶被分配到了同一臺服務器上,這個沒什么影響。但是如果是服務節點有哈希沖突呢?這會導致兩個服務節點在哈希環上對應同一個點,其實我感覺這個問題也不大,因為一方面哈希沖突的概率比較低,另一方面我們可以通過虛擬節點也可減少這種情況。

以上就是詳解Java分布式系統中一致性哈希算法的詳細內容,更多關于Java算法的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
99久久99久久久精品齐齐 | 免费国产一区二区| 精品噜噜噜噜久久久久久久久试看 | 久久久www成人免费毛片麻豆| 国产一区二区三区在线观看免费 | 欧美成人午夜| 久久综合色播五月| av不卡免费在线观看| 久久综合久久99| 不卡一区二区三区四区| 精品美女被调教视频大全网站| 高清在线观看日韩| 精品欧美久久久| 99v久久综合狠狠综合久久| 国产suv精品一区二区6| 91精品国产色综合久久不卡电影 | 亚洲日穴在线视频| 在线成人国产| 一区二区三区中文在线观看| 国产九区一区在线| 图片区小说区区亚洲影院| 乱码第一页成人| 天堂一区二区在线| 在线看不卡av| 国产最新精品精品你懂的| 91精品国产一区二区三区香蕉| 成人综合在线观看| 精品国产凹凸成av人导航| 99在线精品免费| 中文字幕不卡一区| 亚洲伦理一区| 日本午夜一区二区| 欧美日韩的一区二区| 成人丝袜18视频在线观看| 久久青草欧美一区二区三区| 韩日午夜在线资源一区二区| 亚洲国产日韩在线一区模特| 91久久精品一区二区| 经典一区二区三区| 精品国产凹凸成av人网站| 欧美性事免费在线观看| 一区二区三区精品视频| 老妇喷水一区二区三区| 久久国产人妖系列| 日韩一区二区三区视频| 99国产精品国产精品毛片| 国产精品久久久久婷婷二区次| 一区二区三区你懂的| 日韩国产欧美三级| 欧美一级国产精品| 欧美日韩一区二区三区在线观看免| 亚洲精品欧美专区| 在线一区二区三区四区五区| 国产传媒欧美日韩成人| 一本一道久久a久久精品综合蜜臀| 国产乱子伦视频一区二区三区| 久久综合九色综合欧美亚洲| 亚洲国产精品一区二区第一页 | 成人性色生活片| 国产欧美一区二区三区网站 | 亚洲国产综合在线| 欧美亚洲一区二区在线观看| 成人黄页在线观看| 亚洲欧美日韩国产另类专区| 日本韩国欧美国产| 91在线一区二区| 一区二区三区中文在线观看| 欧美视频在线一区| 91视频一区二区三区| 亚洲一区二区三区小说| 日韩一级欧美一级| 精品成人一区| 麻豆国产精品官网| 国产精品私房写真福利视频| 在线观看三级视频欧美| 欧美一区二区三区久久精品茉莉花| 亚洲成人高清在线| 精品久久久久久无| 一本色道久久综合一区| 国产一区久久久| 亚洲欧美综合色| 欧美日韩一区二区不卡| 国产一区日韩欧美| 国产综合色产在线精品| 亚洲色图欧美偷拍| 欧美一卡二卡三卡四卡| av成人毛片| 国产成人99久久亚洲综合精品| 亚洲视频一二三| 欧美一区二区三区影视| 一本色道久久综合亚洲精品不| 成人手机电影网| 爽好多水快深点欧美视频| 久久蜜臀中文字幕| 色婷婷激情久久| 国产精品二区在线| 九色|91porny| 亚洲精品日韩一| 欧美精品一区二| 在线观看日韩毛片| 亚洲国产精品123| 国产91在线|亚洲| 婷婷久久综合九色综合绿巨人 | 3d成人h动漫网站入口| 亚洲精品乱码| a在线播放不卡| 热久久一区二区| 国产精品丝袜一区| 91精品欧美一区二区三区综合在 | 国产精品国产三级欧美二区 | 日韩福利电影在线| 国产精品素人视频| 欧美一区二区视频网站| 国产美女诱惑一区二区| 91啪亚洲精品| 国产一区二区福利| 亚洲一区免费观看| 欧美激情自拍偷拍| 欧美一级一区二区| 欧美中文字幕亚洲一区二区va在线| 亚洲日本国产| 色综合天天综合网天天狠天天 | 欧美成人精品高清在线播放| 色香色香欲天天天影视综合网| 亚洲高清在线| 欧美呦呦网站| 丁香桃色午夜亚洲一区二区三区| 天天影视色香欲综合网老头| 国产精品久久久久久一区二区三区| 在线成人免费视频| 久久久久久久久久久一区| 亚洲精品视频啊美女在线直播| 牛牛国产精品| av中文一区二区三区| 国产在线观看免费一区| 日韩成人伦理电影在线观看| 一区二区三区在线观看国产| 国产精品每日更新在线播放网址| 欧美sm极限捆绑bd| 91精品国产综合久久小美女| 欧美综合视频在线观看| 国产精品美女| 国产在线日韩| 91片在线免费观看| www.欧美色图| 丁香婷婷综合激情五月色| 激情国产一区二区| 七七婷婷婷婷精品国产| 亚洲香肠在线观看| 亚洲精品国产一区二区精华液| 国产精品美女一区二区三区| 2017欧美狠狠色| 日韩丝袜情趣美女图片| 欧美色窝79yyyycom| 久久看片网站| 亚洲欧美清纯在线制服| 一区二区精品国产| 影音先锋国产精品| 91麻豆免费在线观看| 91在线丨porny丨国产| 不卡av电影在线播放| 国产91精品一区二区麻豆网站| 国产美女精品一区二区三区| 蜜乳av一区二区| 人人爽香蕉精品| 日韩av一区二区在线影视| 三级不卡在线观看| 图片区日韩欧美亚洲| 偷窥少妇高潮呻吟av久久免费| 亚洲成年人影院| 亚洲不卡av一区二区三区| 亚洲午夜在线电影| 一二三四社区欧美黄| 亚洲国产视频a| 日日嗨av一区二区三区四区| 日韩av中文字幕一区二区三区| 免费观看久久久4p| 韩国成人精品a∨在线观看| 国产在线精品免费av| 国产精品亚洲第一区在线暖暖韩国 | 久久综合久久综合久久综合| 久久久久九九视频| 国产视频一区二区三区在线观看| 国产欧美1区2区3区| 国产精品欧美久久久久无广告| 国产欧美日韩激情| 国产精品乱人伦| 玉米视频成人免费看| 亚洲一区二区在线视频| 亚洲1区2区3区4区| 美女性感视频久久| 国产激情视频一区二区在线观看 | 久久午夜激情| 欧美日本一区二区| 精品国产一二三| 国产精品色哟哟| 亚洲最色的网站| 美国一区二区三区在线播放| 国产成人自拍高清视频在线免费播放| 成人性生交大片免费看中文|