數據分布方式一哈希與一致性哈希詳解

2020-09-03 997又怎樣

首先,我們來看一下數據分布設計的原則。數據分布設計原則是分布式存儲系統設計的基本原則,指導了哈希和一致性哈希方法的選擇和應用。

數據分布設計原則

實,這裡的數據分布,主要就是數據分片。相信你還記得,我在第24篇文章中與你分享分布式存儲系統的導購時,已經和你提到數據分片技術,它解決了確定數據位置的問題,並著重與你講述了按照數據特徵進行劃分的分片方法。今天,我主要與你講解按照數據範圍,採用哈希一致性哈希等對數據劃分的方法。

假設,現在有上百G數據需要進行分布式存儲,也就是要存儲到不同的節點上。提到這個問題,你可能立刻就會想到很多種方法,比如隨機分布、範圍分布、映射分布等。那麼,我們應該如何選擇到底要使用哪種方法呢?

在分布式數據存儲系統中,存儲方案選型時,通常會考慮數據均勻、數據穩定和節點異構性這三個維度。

從數據均勻的維度考慮,主要包括兩個方面:

不同存儲節點中存儲的數據要儘量均衡,避免讓某一個或某幾個節點存儲壓力過大, 而其他節點卻幾乎沒什麼數據。比如,現在有100G數據,4個同類型節點,通常希望數據存儲時儘可能均衡,比如每個節點存儲25G數據。

另外,用戶訪問也要做到均衡,避免出現某一個或某幾個節點的訪問量很大,但其他節

點卻無人問津的情況。比如,現在有1000個請求,對於上述存儲數據的4個節點,處理用戶訪問請求儘量均衡,比如每個節點處理250個請求,當然這是非常理想的情況,實際情況下,每個節點之間相差不太大即可。

從數據穩定的維度考慮,當存儲節點出現故障需要移除或者擴增時,數據按照分布規則得到的結果應該儘量保持穩定,不要出現大範圍的數據遷移。

比如,現有100G數據,剛開始有4個同類型節點(節點1~4),每個節點存儲25G數據,現在節點2故障了,也就是說每個節點需要存儲100G/3數據。

數據穩定,就是儘可能只遷移節點2.上的數據到其他節點上,而不需要對大範圍或所有數

據進行遷移存儲。當然,如果有擴展同類型節點,也是儘可能小範圍遷移數據到擴展的節點上。具體的遷移方法,可以採用下文介紹的一致性哈希方法。

從節點異構性的維度考慮,不同存儲節點的硬體配置可能差別很大。比如,有的節點硬體配置很高,可以存儲大量數據,也可以承受更多的請求;但,有的節點硬體配置就不怎麼樣,存儲的數據量不能過多,用戶訪問也不能過多。

如果這種差別很大的節點,分到的數據量、用戶訪問量都差不多,本質就是一種不均衡。 所以,一個好的數據分布算法應該考慮節點異構性。

當然,除了上面這3個維度外,我們一般還會考慮隔離故障域、性能穩定性等因素。隔離故障域,是為了保證數據的可用和可靠性。比如,我們通常通過備份來實現數據的可靠性。但如果每個數據及它的備份,被分布到了同- -塊硬碟或節點上,就有點違背備份的初衷了。所以,一個好的數據分布算法,應該為每個數據映射一組存儲節點,這些節點應該儘量在不同的故障域,比如不同機房、不同機架等。

隔離故障域,是為了保證數據的可用和可靠性。比如,我們通常通過備份來實現數據的可靠性。但如果每個數據及它的備份,被分布到了同一塊硬碟或節點上,就有點違背備份的初衷了。所以,一個好的數據分布算法,應該為每個數據映射一組存儲節點,這些節點應該儘量在不同的故障域,比如不同機房、不同機架等。

性能穩定性是指,數據存儲和查詢的效率要有保證,不能因為節點的添加或者移除,造成存儲或訪問性能的嚴重下降。

了解了數據分布的設計原則後,接下來我們再看看主流的數據分布式方法,哈希和一致性哈希吧。其中,哈希和一致性哈希是數據分布的基礎方法,在不同場景下,數據分布設計的原則需要考慮的維度也不一樣。隨著維度的增加,一致性哈希又可進一 步演進為帶 有限負載的一致性哈希和帶虛擬節 點的一致性哈希方法。

接下來,我們就一起看看這4種方法的具體原理和應用場景吧。

數據分布方法

哈希是指,將數據按照提前規定好的函數(哈希函數)映射到相應的存儲節點,即進行一個哈希計算,得到的結果就是數據應該存儲的節點。

一致性哈希同樣是採用哈希函數, 進行兩步哈希:

1.對存儲節點進行哈希計算,也就是對存儲節點做哈希映射;

2.當對數據進行存儲或訪問時,首先對數據進行映射得到一個結果,然後找到比該結果大的第一個存儲節點,就是該數據應該存儲的地方。我會在下面的內容中,與你詳細介紹其中的原理。

總結來講,哈希是一步計算直接得到相應的存儲節點,而一致性哈希需要兩步才可以找到相應的存儲節點。這,是不是就是&34;與&39;a0&39;a1&39; }、 D3:{ id:400, name:『a3&39;a4&39;a5&39;a6&34;id% 節點個數」,通過計算可以得到每個數據應該存入的節點。在這個例子中,哈希函數是&34;分布式體系結構之非集中式結構:眾生平等」中的相關內容。

一致性哈希方法雖然提升了 穩定性,但隨之而來的均勻性問題也比較明顯,即對後繼節點的負載會變大。有節點退出後,該節點的後繼節點需要承擔該節點的所有負載,如果後繼節點承受不住,便會出現節點故障,導致後繼節點的後繼節點也面臨同樣的問題。

那麼,有沒有更好的方法來解決這個問題呢?

Google在2017年提出了帶有限負載的一致性哈希算法,就對這個問題做了一些優化。帶有限負載的一致性哈希

帶有限負載的一致性哈希方法的核心原理是,給每個存儲節點設置了-個存儲上限值來控制存儲節點添加或移除造成的數據不均勻。當數據按照一致性哈希 算法找到相應的存儲節點時,要先判斷該存儲節點是否達到了存儲上限;如果已經達到了上限,則需要繼續尋找該存儲節點順時針方向之後的節點進行存儲。

我們看看如何用帶有限負載的一致性哈希方法,來實現上述案例的數據存儲吧。

如圖所示,假設每個存儲節點設置的上限值為3,按照-致性哈希算法,當存儲數據D3 (id= 400)時,會發現應該存儲到Node1中,但Node1已經存儲了三個數據DO (id= 100)、D1 (id= 200)和D2 (id= 300) ,達到了存儲上限,因此會存儲到.該節點順時針方向的下一個節點Node2中。當然,在存儲前,也會先檢查Node2是否達到了存儲上限,如果達到了,會繼續尋找其他節點。

帶有限負載的一致性哈希方法比較適合同類型節點、節點規模會發生變化的場景。目前,在Google Cloud Pub/Sub、HAProxy 中已經實現該方法,應用於Google、Vimeo 等公司的負載均衡項目中。

其實,哈希、一致性哈希、帶有限負載的一致性哈希,都沒有考慮節點異構性的問題。如果存儲節點的性能好壞不一, 數據分布方案還按照這些方法的話,實還是沒做到數據的均勻分布。

接下來,我們再看一種主要針對存儲節為異構節點場景的方法,即帶虛擬節點的一致性哈希吧。.

帶虛擬節點的一致性哈希

帶虛擬節點的一致性哈希方法,核心思想是根據每個節點的性能,為每個節點劃分不同數量的虛擬節點,並將這些虛擬節點映射到哈希環中,然後再按照一致性哈希算法進行數據映射和存儲。

假設,Node1性能最差,Node2 性能一般,Node3性能最好。以Node1的性能作為參考基準,Node2是Node1的2倍,Node3是Node1的3倍。

因此,Node1 對應一個虛擬節點Node1_ 1, Node2 對應2個虛擬節點Node2_ 1和Node2_ 2,Node3 對應3個虛擬節點Node3_ 1、Node3_ 2和Node3_ 3.假設,虛擬節點Node1. _1、Node2_ 1、Node2_ 2、Node3_ 1、Node3_ 2、Node3_ 3的哈希值,分別為100、200、 300、 400、 500、600。

那麼,按照帶虛擬節點的哈希一致性方法, 數據D0和D6按順時針方向的下一個虛擬存儲節點為Node 1-1,因此節點Node1將會存儲數據DO (id= 100)和D6 (id =700) ;同理,Node2將會存儲數據D1 (id= 200)和D2 (id= 300),Node3將會存儲數據D3 (id= 400)、D4 (id= 500) 和D5 (id = 600)

可以看出,帶虛擬節點的一致性哈希方法比較適合異構節點、節點規模會發生變化的場景。目前Memcached緩存系統實現了該方法,我會在第27篇文章中與你詳細分析。

這種方法不僅解決了節點異構性問題,還提高了系統的穩定性。當節點變化時,會有多個節點共同分擔系統的變化,因此穩定性更高。

比如,當某個節點被移除時,對應該節點的多個虛擬節點均會移除,而這些虛擬節點按順時針方向的下一個虛擬節點,可能會對應不同的物理節點,即這些不同的物理節點共同分擔了節點變化導致的壓力。

當然,這種方法引入了虛擬節點,增加了節點規模,從而增加了節點的維護和管理的複雜度,比如新增一個節點或一個節點故障時, 對應到虛擬節點構建的哈希環上需要新增和刪除多個節點,數據的遷移等操作相應地也會很複雜。

四種數據分布方法對比

為方便理解與記憶,我再通過一個表格和你對比分析下這四種方法吧。請注意,以下方法之間的對比都是相對的比較,實際性能優劣與哈希函數的設定以及具體的數據場景密切相關。

相關焦點

  • 分布式數據緩存中的一致性哈希算法
    一致性哈希算法在分布式緩存領域的 MemCached,負載均衡領域的 Nginx 以及各類 RPC 框架中都有廣泛的應用,它主要是為了解決傳統哈希函數添加哈希表槽位數後要將關鍵字重新映射的問題。本文會介紹一致性哈希算法的原理及其實現,並給出其不同哈希函數實現的性能數據對比,探討Redis 集群的數據分片實現等,文末會給出實現的具體 github 地址。
  • 什麼是一致性哈希算法
    ---數據分片與路由當數據量很大時,通過改善單機硬體資源的縱向擴充方式來存儲數據變得越來越不適用,而通過增加機器數目來獲得水平橫向擴展的方式則越來越流行。因此,就有個問題,如何將這些海量的數據分配到各個機器中?數據分布到各個機器存儲之後,又如何進行查找?這裡主要記錄一致性Hash算法如何將數據分配到各個機器中去。
  • 5分鐘理解一致性哈希算法
    前言一致性哈希算法(Consistent Hashing)在分布式系統的應用還是十分廣泛的,本文儘量結合業務場景快速講解一致性哈希算法的應用及與其相關的話題。1 分布式緩存隨著業務的擴展,流量的劇增,單體項目逐漸劃分為分布式系統。對於經常使用的數據,我們可以使用Redis作為緩存機制,減少數據層的壓力。
  • 簡明講解一致性哈希算法
    簡明講解一致性哈希算法哈希算法#如果我們用(用戶id)%伺服器機器數這樣的方法來分配伺服器。雖然我們能保證數據的均勻性,但穩定性差,比如我們增加一個節點,會導致大量的映射失效。所以哈希算法只適用於節點數比較固定的情況,並不能很好的應對節點的變化。一致性哈希算法#這個時候一致性算法就來了,你看這個哈希環它是又大又圓,用它來降低映射關係大量失效的可能性剛剛好。任何一條線段都有無數個點,這個大家應該沒什麼意見吧?所以理論上這個哈希圈是能存儲無限多的東西的。
  • 圖解一致性哈希算法,全網(小區區域網)最通俗易懂
    緩存系統負載均衡在分布式集群緩存的負載均衡實現中,比如 memcached 緩存集群,需要把緩存數據的 key 利用哈希函數散列,這樣緩存數據能夠均勻分布到各個分布式存儲節點上,要實現這樣的負載均衡一般可以用哈希算法來實現。
  • 10分鐘了解一致性哈希算法,全網(小區區域網)(建議收藏)
    緩存系統負載均衡在分布式集群緩存的負載均衡實現中,比如 memcached 緩存集群,需要把緩存數據的 key 利用哈希函數散列,這樣緩存數據能夠均勻分布到各個分布式存儲節點上,要實現這樣的負載均衡一般可以用哈希算法來實現。
  • 職場|程式設計師必須知道的一致性哈希路由算法
    3臺機器的情況下,老數據取數據變化://從伺服器2上取數據,獲取失敗,實際數據存在伺服器0上hash(「test1」)%4=2;//從伺服器3上取數據,獲取失敗,實際數據存在伺服器1上hash(「test2」)%4=3;從伺服器0上取數據,獲取失敗,實際數據存在伺服器2上hash(「test3」)%4=
  • 一口氣講透一致性哈希(Hash),助力「碼農變身」
    如今雲計算、大數據、物聯網、AI的興起,使得分布系統得到了前所未有的廣泛應用,然而由於分布式系統具有極高的複雜度,帶來了許多難題,一致性哈希就是為了解決分布式難題之一應運而生的,本篇主要圖示講解一致性哈希的原理及其應用,助力碼農變身。
  • Redis Sharding 集群跟一致性哈希有什麼瓜葛?
    但在開始介紹之前一定要接受一個前提,一致性哈希算法可以做到:均衡性:不同對象經哈希後的哈希值在哈希環內(即hash family)能保證儘量均勻分布確保均衡落入到不同節點;如果使用一致性哈希算法的話(我這裡畫了個概念圖方便理解),算法會針對每個物理節點(Node)虛擬出多個虛擬節點(這裡簡稱Virtual Node或者VNode),這樣在整個哈希環空間內就有多個互相交錯的虛擬節點,那數據分布得更均衡了而避免對於某臺伺服器的讀寫壓力,一般來說虛擬節點越多數據分布得越均勻(曾經在某個文章看過壓測數據,當虛擬節點數達到
  • 基於協同矩陣分解的多模態數據的哈希方法
    其中,基於哈希的模型中最值得借鑑的是位置敏感哈希(LSH),其基本思想是將原始數據映射到漢明空間,同時保留它們的相似性。LSH 可以很有效地處理相似性搜索,因為在計算二進位碼之間的漢明距離時,應用了位運算。在標準 LSH 的基礎上, 也可以採用一些機器學習的方法來設計有效的緊湊哈希。
  • Go語言數據結構 | 哈希表(1)
    3.3 哈希表這一節會介紹 Go 語言中的另一個集合元素 — 哈希,也就是 Map 的實現原理;哈希表是除了數組之外,最常見的數據結構,幾乎所有的語言都會有數組和哈希表這兩種集合元素比較實際的方式是讓哈希函數的結果能夠儘可能的均勻分布,然後通過工程上的手段解決哈希碰撞的問題,但是哈希的結果一定要儘可能均勻,結果不均勻的哈希函數會造成更多的衝突並導致更差的讀寫性能。
  • 關於哈希的一切,都在這裡了
    上一節,我們一起學習了,在Java中如何構建高性能隊列,裡面牽涉到很多底層的知識,不知道你有Get到多少呢?!本節,我想跟著大家一起重新學習下關於哈希的一切——哈希、哈希函數、哈希表。這三者有什麼樣的愛恨情仇?
  • 關於哈希的一切,都在這裡了!
    前言本文收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與算法的知識。你好,我是彤哥。上一節,我們一起學習了,在Java中如何構建高性能隊列,裡面牽涉到很多底層的知識,不知道你有Get到多少呢?!本節,我想跟著大家一起重新學習下關於哈希的一切——哈希、哈希函數、哈希表。
  • 一文告訴你誇克區塊鏈中哈希思想與哈希表構造到底是什麼!
    散列表(Hash table,也叫哈希表),是根據鍵(Key)而直接訪問在內存儲存位置的數據結構。也就是說,它通過計算一個關於鍵值的函數,將所需查詢的數據映射到表中一個位置來訪問記錄,這加快了查找速度。這個映射函數稱做散列函數,存放記錄的數組稱做散列表。
  • 「編程學習」淺談哈希表及用C語言構建哈希表
    哈希表:通過key-value而直接進行訪問的數據結構,不用經過關鍵值間的比較,從而省去了大量處理時間。②計算出來的地址分布均勻,即對任一關鍵字k,f(k) 對應不同地址的概率相等,目的是儘可能減少衝突。
  • 局部敏感哈希(LSH)
    一. 近鄰搜索局部敏感哈希,英文locality-sensetive hashing,常簡稱為LSH。局部敏感哈希在部分中文文獻中也會被稱做位置敏感哈希。LSH是一種哈希算法,最早在1998年由Indyk在上提出。
  • 機器學習時代的哈希算法,將如何更高效地索引數據
    MurmurHash 和 Tabulation Hashing 是乘法移位哈希函數家族的強力替代品。對這些哈希函數進行的基準測試包括檢查它們的計算速度,生成的哈希碼的分布以及它們處理不同類型數據(例如除整數以外的字符串和浮點數)的靈活性。如果我們選擇一個好的哈希函數,我們可以降低衝突率並且仍然保持較高的計算速度。
  • 什麼是哈希算法?
    我們要講的哈希算法也是這樣,原始數據經過哈希算法加工以後得到的數據就叫作哈希值(Hash Value)。哈希算法並不是一個算法,而是一大類算法的統稱。由於哈希算法的技術細節已經超綱,我們在這裡不討論它的原理,只介紹這種算法的性質和應用。
  • Redis命令——哈希數據結構命令剖析
    在數據結構中,哈希表也叫散列表,是根據key訪問數據結構空間,也是就是說根據鍵計算出存儲數據空間的位置。在Redis中哈希的含義是鍵與值組成的關聯映射,鍵與值是由字符串組成。這種數據結構優勢是1 能快速查找出元素。2 符合實際需求,比如要存儲員工的身份證信息。
  • 使能資料庫的數據結構 - 概述&哈希索引
    為了在資料庫裡高效的查找指定key的value,我們需要一個不一樣的數據結構:一個index索引。這背後的含義是:在邊上保有一些額外的元數據,用來充當路標來幫助我們定位你想要的數據。如果要以幾種不同的方式搜索相同的數據,則可能需要在數據的不同部分使用多個不同的索引。索引是從主要數據派生的附加結構。