Redis(二)---數據分區

Redis分區

#1 什麼是數據分區

分佈式數據庫首先要解決把整個數據集按照分區規則映射到多個節點的問題,即把數據集劃分到多個節點上,每個節點負責整體數據的一個子集。

在這裏插入圖片描述

數據分佈通常有 哈希分區 和 順序分區 兩種方式, 如下:

  • 分區方式 特點 相關產品 哈希分區 離散程度好,數據分佈與業務無關,無法順序訪問 Redis Cluster,Cassandra,Dynamo
  • 順序分區 離散程度易傾斜,數據分佈與業務相關,可以順序訪問 BigTable,HBase,Hypertable 由於Redis Cluster 採用哈希分區規則,這裏重點討論哈希分區(上圖中的分區規則)

#2 Redis爲什麼要分區

  • 通過利用多臺計算機內存的和值,允許我們構造更大的數據庫。
  • 通過多核和多臺計算機,允許我們擴展計算能力;通過多臺計算機和網絡適配器,允許我們擴展網絡帶寬。

#3 哈希分區

#3.1 節點取餘分區

使用特定的數據,如Redis的鍵或用戶ID,再根據節點數量 N 使用公式:hash(key)% N 計算出 哈希值,用來決定數據 映射 到哪一個節點上。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MUf971mZ-1583258339448)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200302152551-image.png)]

優點:

這種方式的突出優點是簡單性,常用於數據庫的分庫分表規則。一般採用預分區的方式,提前根據數據量規劃好分區數,比如劃分爲 512 或 1024 張表,保證可支撐未來一段時間的數據容量,再根據負載情況將表遷移到其他數據庫中。擴容時通常採用翻倍擴容,避免數據映射全部被打亂,導致全量遷移的情況。

缺點:

當節點數量變化時,如擴容 或 收縮 節點,數據節點映射關係 需要重新計算,會導致數據的重新遷移。

#3.2 一致性哈希分區

#3.2.1 什麼是一致性哈希 ?

通過#3.1 節點求餘分析了它的劣勢,當節點數發生變動的時候,幾乎所有的數據都會移動(不移動的應該是運氣比較好吧前後取模都是同一個值),這個代價很大。此時的問題從水平如何拆分變成了,當增加或者刪除節點時,對於大多數記錄,保證原來分配到的某個節點,現在仍然應該分配到那個節點,將數據遷移量的降到最低,這就是一致性哈希要做的事情。

#3.2.2 一致性哈希思想

一致性 Hash 算法也是使用取模的思想,只是,剛纔描述的取模法是對節點數量進行取模,而一致性Hash算法是對 2^32 取模,什麼意思呢?簡單來說,一致性Hash算法將整個哈希值空間組織成一個虛擬的圓環,如假設某哈希函數H的值空間爲0-2^32-1(即哈希值是一個32位無符號整形),整個哈希環如下,從 0 ~ 2^32-1 代表的分別是一個個的節點,這個環也叫哈希環

20200304013155-image.png

然後我們將我們的節點進行一次哈希,按照一定的規則,比如按照 key的哈希值,讓節點落在哈希環上。比如此時我們可能得到了如下圖的環:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zXS6WS4m-1583258339452)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200304013336-image.png)]

然後就是需要通過數據 key 找到對應的服務器然後存儲了,我們約定,通過數據 key 的哈希值落在哈希環上的節點,如果命中了機器節點就落在這個機器上,否則落在順時針直到碰到第一個機器。如下圖所示 : A 的哈希值落在了 D2 節點的前面,往下找落在了 D2 節點上,D的哈希值 在 D1 節點的前面,往下找到了 D1 節點,B的哈希值剛好落在了D1 節點上,依次~~~

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-e27v22tm-1583258339455)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200304014350-image.png)]

一致性哈希主要就是解決當機器減少或增加的時候,大面積的數據重新哈希的問題,主要從下面 2 個方向去考慮的,當節點宕機時,數據記錄會被定位到下一個節點上,當新增節點的時候 ,相關區間內的數據記錄就需要重新哈希。

優點:

加入 和 刪除 節點隻影響 哈希環 中 順時針方向 的 相鄰的節點,對其他節點無影響。

缺點:

一致性Hash算法在服務節點太少時,容易因爲節點分部不均勻而造成數據傾斜(被緩存的對象大部分集中緩存在某一臺服務器上)問題。比如只有 2 臺機器,這 2 臺機器離的很近,那麼順時針第一個機器節點上將存在大量的數據,第二個機器節點上數據會很少。如下圖所示,D0 機器承載了絕大多數的數據

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JnQ7l5jo-1583258339457)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200304014606-image.png)]

#3.3 虛擬槽分區

虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把所有數據映射到一個固定範圍的整數集合中,整數定義爲槽(slot)。這個範圍一般遠遠大於節點數,比如 Redis Cluster 槽範圍是 0 ~ 16383。Redis 集羣包含了 16384 個哈希槽,每個 Key 經過計算後會落在一個具體的槽位上,而每個槽位落到哪個節點上,根據自己的節點配置,如圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1V7f6Scy-1583258339459)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200302153056-image.png)]

假設,當前集羣有 5 個節點,每個節點平均大約負責 3276 個槽。由於採用高質量的哈希算法,每個槽所映射的數據通常比較均勻,將數據平均劃分到 5 個節點進行數據分區。Redis Cluster 就是採用虛擬槽分區。

節點1: 包含 0 到 3276 號哈希槽。

節點2:包含 3277 到 6553 號哈希槽。

節點3:包含 6554 到 9830 號哈希槽。

節點4:包含 9831 到 13107 號哈希槽。

節點5:包含 13108 到 16383 號哈希槽。

注意一個思想,槽位是落在節點上的,且我們可以任意配置那些槽位落在哪個節點上

這種結構很容易添加或者刪除節點。如果增加一個節點 6,就需要從節點 1 ~ 5 獲得部分槽分配到節點 6 上。如果想移除節點 1,需要將節點 1 中的槽移到節點 2 ~ 5 上,然後將沒有任何槽的節點 1 從集羣中移除即可。

由於從一個節點將 哈希槽 移動到另一個節點並不會 停止服務,所以無論 添加刪除或者改變某個節點的哈希槽的數量都不會造成集羣不可用的狀態.

#4 Redis的數據分區

Redis Cluster 採用虛擬槽分區(Redis Cluster是Redis自帶的集羣),所有的鍵根據哈希函數映射到 0~16383 整數槽內,計算公式:slot = CRC16(key)& 16383。每個節點負責維護一部分槽以及槽所映射的鍵值數據,如圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6ElDOr3l-1583258339465)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200302153325-image.png)]

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