国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

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

發(fā)布時(shí)間:2021-07-17 21:51 來(lái)源:腳本之家 閱讀:0 作者:JiaJian 欄目: 編程語(yǔ)言 歡迎投稿:712375056

目錄

        業(yè)務(wù)場(chǎng)景

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

        我們以負載均衡為例,常見(jiàn)的負載均衡方法有很多,但是它們的優(yōu)缺點(diǎn)也都很明顯:

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

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

        使用Hash取模的問(wèn)題

        1.負載均衡

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

        例如現有IP地址 10.58.34.31,對IP哈希取模策時(shí),計算結果為2,即訪(fǎng)問(wèn)編號為2的服務(wù)器:

        String ip = "10.58.34.31";
        int v1 = hash(ip) % 3;
        System.out.println("訪(fǎng)問(wèn)服務(wù)器:" + v1);// 訪(fǎng)問(wèn)服務(wù)器:2

        如果此時(shí)服務(wù)器2宕機了,則會(huì )導致所有計算結果為2的 IP 對應的用戶(hù)都訪(fǎng)問(wèn)異常(包括上例中的IP)?;蛘吣阈略隽艘慌_服務(wù)器3,這時(shí)不修改N值的話(huà)那么服務(wù)器3永遠不會(huì )被訪(fǎng)問(wèn)到。

        當然如果你能動(dòng)態(tài)獲取到當前可用服務(wù)器的個(gè)數,亦即N值是根據當前可用服務(wù)器個(gè)數動(dòng)態(tài)來(lái)變化的,則可解決此問(wèn)題。但是對于類(lèi)似要在特定地區或特定IP來(lái)訪(fǎng)問(wèn)特定服務(wù)器的這種需求就會(huì )造成訪(fǎng)問(wèn)偏差。

        2.分庫分表

        負載均衡中有這種問(wèn)題,那么分庫分表中同樣也有這樣的問(wèn)題。例如隨著(zhù)業(yè)務(wù)的飛速增長(cháng),我們的注冊用戶(hù)也越來(lái)越多,單個(gè)用戶(hù)表數量已經(jīng)達到千萬(wàn)級甚至更大。由于Mysql的單表建議百萬(wàn)級數據存儲,所以這時(shí)為了保證系統查詢(xún)和運行效率,肯定會(huì )考慮到分庫分表。

        對于分庫分表,數據的分配是個(gè)重要的問(wèn)題,你需要保證數據分配在這個(gè)服務(wù)器,那么在查詢(xún)時(shí)也需要到該服務(wù)器上來(lái)查詢(xún),否則會(huì )造成數據查詢(xún)丟失的問(wèn)題。

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

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

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

        之后業(yè)務(wù)數量持續增長(cháng),又新增一臺用戶(hù)服務(wù)庫,當我們根據ID=1010去查詢(xún)數據時(shí),路由計算方式為:

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

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

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

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

        基本思想原理

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

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

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

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

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

        這里需要注意一點(diǎn):

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

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

        整個(gè)空間圓按順時(shí)針?lè )较虿季?,圓環(huán)的正上方的點(diǎn)代表0,0點(diǎn)右側的第一個(gè)點(diǎn)代表1。以此類(lèi)推2、3、4、5、6……直到232-1,也就是說(shuō)0點(diǎn)左側的第一個(gè)點(diǎn)代表232-1, 0和2^32-1在零點(diǎn)中方向重合,我們把這個(gè)由2^32個(gè)點(diǎn)組成的圓環(huán)稱(chēng)為 Hash環(huán)。

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

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

        最后會(huì )得到一個(gè) [0, 2^32-1]之間的一個(gè)無(wú)符號整形數,這個(gè)整數就代表服務(wù)器的編號。同時(shí)這個(gè)整數肯定處于[0, 2^32-1]之間,那么,上圖中的 hash 環(huán)上必定有一個(gè)點(diǎn)與這個(gè)整數對應。那么這個(gè)服務(wù)器就可以映射到這個(gè)環(huán)上。

        多個(gè)服務(wù)器都通過(guò)這種方式進(jìn)行計算,最后都會(huì )各自映射到圓環(huán)上的某個(gè)點(diǎn),這樣每臺機器就能確定其在哈希環(huán)上的位置,如下圖所示。

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

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

        從上圖可以看出 用戶(hù)1 順時(shí)針遇到的第一臺服務(wù)器是 服務(wù)器3 ,所以該用戶(hù)被分配給服務(wù)器3來(lái)提供服務(wù)。同理可以看出用戶(hù)2被分配給了服務(wù)器2。

        1. 新增服務(wù)器節點(diǎn)

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

        可以發(fā)現,原來(lái)訪(fǎng)問(wèn)服務(wù)器3的用戶(hù)1現在訪(fǎng)問(wèn)的對象是服務(wù)器4,用戶(hù)能正常訪(fǎng)問(wèn)且服務(wù)不需要停機就可以自動(dòng)切換。

        2. 刪除服務(wù)器節點(diǎn)

        如果這時(shí)某臺服務(wù)器異常宕機或者運維撤銷(xiāo)了一臺服務(wù)器,那么這時(shí)會(huì )發(fā)生什么情況呢?如下圖所示,假設我們撤銷(xiāo)了服務(wù)器2。

        可以看出,我們服務(wù)仍然能正常提供服務(wù),只不過(guò)這時(shí)用戶(hù)2會(huì )被分配到服務(wù)1上了而已。

        通過(guò)一致性哈希的方式,我們提高了我們系統的容錯性和可擴展性,分布式節點(diǎn)的變動(dòng)不會(huì )影響整個(gè)系統的運行且不需要我們做一些人為的調整策略。

        Hash環(huán)的數據傾斜問(wèn)題

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

        例如當有4個(gè)服務(wù)節點(diǎn)時(shí),我們把哈希環(huán)認為是一個(gè)圓盤(pán)時(shí)鐘,我們并不能保證4個(gè)服務(wù)節點(diǎn)剛好均勻的落在時(shí)鐘的 12、3、6、9點(diǎn)上。

        分布不均勻就會(huì )產(chǎn)生一個(gè)問(wèn)題,用戶(hù)的請求訪(fǎng)問(wèn)就會(huì )不均勻,同時(shí)4個(gè)服務(wù)承受的壓力就會(huì )不均勻。這種問(wèn)題現象我們稱(chēng)之為,Hash環(huán)的數據傾斜問(wèn)題。

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

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

        既然沒(méi)有多余的真正的物理服務(wù)器節點(diǎn),我們就只能將現有的物理節點(diǎn)通過(guò)虛擬的方法復制出來(lái)。

        這些由實(shí)際節點(diǎn)虛擬復制而來(lái)的節點(diǎn)被稱(chēng)為 "虛擬節點(diǎn)",即對每一個(gè)服務(wù)節點(diǎn)計算多個(gè)哈希,每個(gè)計算結果位置都放置一個(gè)此服務(wù)節點(diǎn),稱(chēng)為虛擬節點(diǎn)。具體做法可以在服務(wù)器IP或主機名的后面增加編號來(lái)實(shí)現。

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

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

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

        此時(shí),環(huán)形空間中不再有物理節點(diǎn) 服務(wù)器1,服務(wù)器2,……,替代的是只有虛擬節點(diǎn) Server1-A,Server1-B,Server2-A,Server2-B,……。

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

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

        總結

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

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

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

        以上就是詳解Java分布式系統中一致性哈希算法的詳細內容,更多關(guān)于Java算法的資料請關(guān)注腳本之家其它相關(guān)文章!

        免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

        久久婷婷色香五月综合缴缴情| 又大又硬又黄又刺激的免费视频 | 亚洲国产欧美人成| 久久天天躁狠狠躁夜夜2020| 青青青国产免费线在| 人妻少妇无码专视频在线|