借 redis cluster 集羣,聊一聊集羣中數據分佈算法

Redis Cluster 集羣中涉及到了數據分佈問題,由於 redis cluster 是多 master 的結構,每一個 master 都是能夠提供存儲服務的,這就會涉及到數據分佈的問題,在新的 redis 版本中採用的是虛擬槽分區技術來解決數據分佈的問題,關於什麼是虛擬槽分區技術咱們後面會詳細的介紹。在集羣中除了虛擬槽分區技術以外,還有幾種數據分佈的算法,好比哈希算法,一致性哈希算法,這篇文章咱們就來一塊兒聊一聊這幾種數據分佈算法。redis

由於是集羣,因此咱們須要一個大前提,在這篇文章中假設 redis cluster 集羣中有三臺 master,咱們須要存儲的數據集爲:[{id:1,"name":"1"},{id:2,name:"2"},{id:3,name:"3"},{id:4,name:"4"},{id:5:"name":"5"},{id:6,"name":"6"}],在這個大前提下,咱們來聊一聊集羣中的數據分佈算法。算法

哈希算法

哈希算法在分佈式架構中應用普遍,不只僅是數據存儲,還有負載均衡等應用上有用的比較多,哈希算法的思想很是簡單,也許你知道 HashMap 的哈希函數,哈希算法跟 HashMap 同樣,也是經過一個哈希函數獲得某一個數字,而後根據數字找到相應的服務器。哈希算法的哈希函數比較簡單,通常是根據某個key的值或者key 的哈希值與當前可用的 master節點數取模,根據取模的值獲取具體的服務器。哈希算法服務結構模型圖以下圖所示:服務器

哈希算法結構模型圖

用咱們前面假設的數據,利用哈希算法來實驗一把,加深咱們對哈希算法在分佈式中的應用的理。咱們假設哈希算法中的哈希函數爲「id % master 節點數」,結果爲 0 的數據存放到 server1 服務器上,結果爲 1 的數據存放到 server2 服務器上,結果爲 2 的數據存放到 server3 服務器上。微信

因此通過哈希算法以後,id=三、id=6 的數據與 master 節點數取模爲 0 (3%3=0,6%3=0),因此這兩個數據會存放到 server1 服務器 ,以此類推,id=一、id=4 的數據將存放到 server2 服務器中,id=二、id=5 的數據將存放到 server3 上,這時候服務器存儲數據以下圖所示:架構

服務器存儲數據

這就是哈希算法在分佈式中的做用,比較簡單,能夠看出只要你哈希函數設計的好,數據在各個服務器上是比較均勻分佈的,可是哈希算法有一個致命的缺點:擴展性特別的差,好比咱們的集羣中,服務器server3 宕機了,這時候集羣中可用的機器只有兩臺了,這樣哈希函數就變成了id % 2了,這就會致使一個問題,全部的數據須要從新計算,找到新的存儲節點,每次有服務器宕機或者添加機器時,都須要進行大量的數據遷移,這會使得系統的可用性、穩定性變差。負載均衡

一致性哈希算法

一致性哈希算法能夠說是哈希算法的升級版,解決了哈希算法擴展性差的問題,一致性哈希算法跟哈希算法不同,一致性哈希算法會將服務器和數據都經過哈希函數映射到一個首尾相連的哈希環上,存儲節點映射能夠根據 ip 地址來進行哈希取值,數據映射到哈希環上後按照順時針的方向查找存儲節點,即從數據映射在環上的位置開始,順時針方向找到的第一個存儲節點,那麼他就存儲在這個節點上分佈式

咱們使用一致性哈希算法來存儲咱們的數據,我畫了一張圖來模擬一致性哈希算法可能出現的結果:函數

一致性算法模擬存儲圖

咱們先來解讀一下這張圖,按照一致性哈希算法的規則,數據沿着順時針的方向查找數據,那麼 id=4 的數據存放在 server1 服務器,id=2 的數據存放在服務器 server2 上,id=三、id=一、id=五、id=6 的數據都存放在服務器 server3 上,若是你比較敏感的話,也許你就會發現一致性哈希算法的不足之處, 從圖中能夠看出,咱們六條數據分佈不均勻,並非每臺服務器存儲 2 條數據,並且差距好像還有點大,這裏咱們就要來講一說一致性哈希算法的缺點:一致性哈希算法會會形成數據分佈不均勻的問題或者叫作數據傾斜問題,就像咱們圖中那樣,數據分佈不均勻可能會形成某一個節點的負載過大,從而宕機。形成數據分佈不均勻有如下兩種狀況:性能

  • 第一:哈希函數的緣由,通過哈希函數以後服務器在哈希環上的分佈不均勻,服務器之間的間距不相等,這樣就會致使數據不均勻。
  • 第二:某服務器宕機了,後繼節點就須要承受本來屬於宕機機器的數據,這樣也會形成數據不均勻。

前面咱們提到過一致性哈希算法解決了哈希算法中擴展性差的問題,這個怎麼理解呢?咱們來看看,在一致性哈希算法中當有存儲節點加入或者退出時,只會影響應該該節點的後繼節點,舉個例子說明一下,例如咱們要在服務器server3 和服務 server2 之間加入了一個服務器存儲節點 server4,只會對服務器server3 形成影響,本來存儲到服務器server3 上的數據有一部分會落入到服務器 server4 上,對服務器 server1 和 server2 並無任何影響,這樣就不會進行大量的數據遷移,擴展性就變強了。學習

帶有限負載的一致性哈希算法

由於一致性哈希算法的數據分佈不均勻的問題,Google 在 2017 年提出了帶有限負載的一致性哈希算法來解決這個問題,帶有限負載的一致性哈希算法思想比較簡單,給每一個存儲節點設置了一個存儲上限值來控制存儲節點添加或移除形成的數據不均勻,當數據按照一致性哈希算法找到相應的存儲節點時,要先判斷該存儲節點是否達到了存儲上限;若是已經達到了上限,則須要繼續尋找該存儲節點順時針方向以後的節點進行存儲。

咱們利用帶有限負載的一致性哈希算法來改進上面的數據存儲,咱們限定每臺服務器節點存儲的數據上限爲 2 ,數據插入的順序就按照 ID 大小的順序,一樣我也畫了一張模擬圖:

帶有限負載的一致性哈希算法

一塊兒來分析一下這張圖,由於咱們的添加順序是按照 id 大小的順序,因此前四個數據都沒有問題,這時候的服務器都沒有超過最高負載數量,id=5 的數據落在了服務器server2 和服務器server3 之間,本應該是存儲在服務器server3 上,可是因爲此時的服務器server3 上已經存儲了 id=一、id=3 的數據達到了最高限定,所以 id=5 的數據會沿着順時針的方向繼續往下尋找服務器,下一個服務器就是server1,此時的服務器server1 就存儲了 id=4 的數據並無達到上限,因此 id=5 的數據就會存儲在服務器server1,id=6 的數據一樣的道理。這樣就利用帶有限負載的一致性哈希算法解決了一致性哈希算法中數據分佈不均勻的問題。

帶虛擬節點的一致性哈希算法

帶有限負載的一致性哈希算法也有一個問題,那就是每臺服務器的性能配置可能存在不同,若是規定數量太小的話,對於配置高的服務器來講有點浪費,這是由於服務器之間可能存在差別,叫作服務器之間的異構性,爲了解決服務器之間的異構性問題,引入了一種叫作帶虛擬節點的一致性哈希算法,帶虛擬節點的一致性哈希算法核心思想是:根據每一個節點的性能爲每一個節點劃分不一樣數量的虛擬節點,並將這些虛擬節點映射到哈希環中,而後再按照一致性哈希算法進行數據映射和存儲

爲了演示帶虛擬節點的一致性哈希算法,咱們先作一個假設服務器server3是配置最差的,因此咱們以服務器server3 爲基準,服務器server2 是服務器server3 的兩倍,服務器server1 是服務器server3 的三倍,有了這個前提以後,咱們就能夠來創建虛擬節點,咱們假設服務器server3 的虛擬節點爲服務器server3_1,服務器server2 就有兩個虛擬節點服務器server2_一、服務器server2_2,服務器server1 有三個虛擬節點 服務器server1_一、服務器server1_二、服務器server1_3。我仍是跟前面同樣畫了一張模擬圖:

落到虛擬節點上的數據都會存到對應的物理服務器上,因此經過帶虛擬節點的一致性哈希算法後,數據存儲結果爲:數據id=二、id=三、id=5 的數據都會存儲到服務器server1 上,id=1 的數據將會存儲到服務器server2 上,數據 id=四、id=6 都會存放到服務器server3上。

虛擬節點可讓配置好的服務器存儲更多的數據,這樣就解決了系統異構性的問題,同時因爲大量的虛擬節點的存在 在數據遷移時數據會落到不一樣的物理機上,這樣就減少了數據遷移時某臺服務器的分擔壓力,可以保證系統的穩定性。

虛擬槽分區

虛擬槽分區是 redis cluster 中默認的數據分佈技術,虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把全部數據映射到一個固定範圍的整數集合中,這個整數定義爲槽(slot),並且這個槽的個數通常遠遠的大於節點數。

在 redis cluster 中有16384(0~16383)個槽,會將這些槽平均分配到每一個 master 上,在存儲數據時利用 CRC16 算法,具體的計算公式爲:slot=CRC16(key)/16384 來計算 key 屬於哪一個槽。在咱們的集羣環境中,一個 key 的存儲或者查找過程,可能以下圖所示:

虛擬槽分區解耦了數據與節點的關係,經過引入槽,讓槽成爲集羣內數據管理和遷移的基本單位,簡化了節點擴容和收縮難度,你只須要關注數據在哪一個槽,並不須要關心數據在哪一個節點上。因此虛擬槽分區能夠說比較好的兼容了數據均勻分佈和擴展性的問題。

以上就是我要分享關於集羣中數據分佈的技術,但願本文的內容對你們的學習或者工做能帶來必定的幫助,感謝你們的支持

最後

目前互聯網上不少大佬都有數據分佈相關文章,若有雷同,請多多包涵了。原創不易,碼字不易,還但願你們多多支持。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,和平頭哥一塊兒學習,一塊兒進步。

平頭哥的技術博文
相關文章
相關標籤/搜索