自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

借Redis Cluster集群,聊一聊集群中數(shù)據(jù)分布算法

開發(fā) 前端 算法 Redis
最近看 redis cluster 集群,在 Redis Cluster 集群中涉及到了數(shù)據(jù)分布問題,因為 redis cluster 是多 master 的結(jié)構(gòu),每個 master 都是可以提供存儲服務(wù)的,這就會涉及到數(shù)據(jù)分布的問題,所以借著個機(jī)會聊一聊分布式中的數(shù)據(jù)分布算法。

最近看 Redis Cluster 集群,在 Redis Cluster 集群中涉及到了數(shù)據(jù)分布問題,因為 Redis Cluster 是多 master 的結(jié)構(gòu),每個 master 都是可以提供存儲服務(wù)的,這就會涉及到數(shù)據(jù)分布的問題,所以借這個機(jī)會聊一聊分布式中的數(shù)據(jù)分布算法,在新的 redis 版本中采用的是虛擬槽分區(qū)技術(shù)來解決數(shù)據(jù)分布的問題,關(guān)于什么是虛擬槽分區(qū)技術(shù)我們后面會詳細(xì)的介紹。在分布式集群中除了虛擬槽分區(qū)技術(shù)之外,還有幾種數(shù)據(jù)分布的算法,比如哈希算法,一致性哈希算法,這篇文章我們就來一起聊一聊這幾種數(shù)據(jù)分布算法。

[[285493]]

因為是集群,所以我們需要一個大前提,在這篇文章中假設(shè) redis cluster 集群中有三臺 master,我們需要存儲的數(shù)據(jù)集為:[{id:1,"name":"1"},{id:2,name:"2"},{id:3,name:"3"},{id:4,name:"4"},{id:5:"name":"5"},{id:6,"name":"6"}],在這個大前提下,我們來聊一聊集群中的數(shù)據(jù)分布算法。

哈希算法

哈希算法在分布式架構(gòu)中應(yīng)用廣泛,不僅僅是數(shù)據(jù)存儲,還有負(fù)載均衡等應(yīng)用上有用的比較多,哈希算法的思想非常簡單,也許你知道 HashMap 的哈希函數(shù),哈希算法跟 HashMap 一樣,也是通過一個哈希函數(shù)得到某一個數(shù)字,然后根據(jù)數(shù)字找到相應(yīng)的服務(wù)器。哈希算法的哈希函數(shù)比較簡單,一般是根據(jù)某個key的值或者key 的哈希值與當(dāng)前可用的 master節(jié)點(diǎn)數(shù)取模,根據(jù)取模的值獲取具體的服務(wù)器。哈希算法服務(wù)結(jié)構(gòu)模型圖如下圖所示: 

哈希算法結(jié)構(gòu)模型圖

用我們前面假設(shè)的數(shù)據(jù),利用哈希算法來實(shí)驗一把,加深我們對哈希算法在分布式中的應(yīng)用的理。我們假設(shè)哈希算法中的哈希函數(shù)為“id % master 節(jié)點(diǎn)數(shù)”,結(jié)果為 0 的數(shù)據(jù)存放到 server1 服務(wù)器上,結(jié)果為 1 的數(shù)據(jù)存放到 server2 服務(wù)器上,結(jié)果為 2 的數(shù)據(jù)存放到 server3 服務(wù)器上。

所以經(jīng)過哈希算法之后,id=3、id=6 的數(shù)據(jù)與 master 節(jié)點(diǎn)數(shù)取模為 0 (3%3=0,6%3=0),所以這兩個數(shù)據(jù)會存放到 server1 服務(wù)器 ,以此類推,id=1、id=4 的數(shù)據(jù)將存放到 server2 服務(wù)器中,id=2、id=5 的數(shù)據(jù)將存放到 server3 上,這時候服務(wù)器存儲數(shù)據(jù)如下圖所示:

服務(wù)器存儲數(shù)據(jù)

這就是哈希算法在分布式中的作用,比較簡單,可以看出只要你哈希函數(shù)設(shè)計的好,數(shù)據(jù)在各個服務(wù)器上是比較均勻分布的,但是哈希算法有一個致命的缺點(diǎn):擴(kuò)展性特別的差,比如我們的集群中,服務(wù)器server3 宕機(jī)了,這時候集群中可用的機(jī)器只有兩臺了,這樣哈希函數(shù)就變成了id % 2了,這就會導(dǎo)致一個問題,所有的數(shù)據(jù)需要重新計算,找到新的存儲節(jié)點(diǎn),每次有服務(wù)器宕機(jī)或者添加機(jī)器時,都需要進(jìn)行大量的數(shù)據(jù)遷移,這會使得系統(tǒng)的可用性、穩(wěn)定性變差。

一致性哈希算法

一致性哈希算法可以說是哈希算法的升級版,解決了哈希算法擴(kuò)展性差的問題,一致性哈希算法跟哈希算法不一樣,一致性哈希算法會將服務(wù)器和數(shù)據(jù)都通過哈希函數(shù)映射到一個首尾相連的哈希環(huán)上,存儲節(jié)點(diǎn)映射可以根據(jù) ip 地址來進(jìn)行哈希取值,數(shù)據(jù)映射到哈希環(huán)上后按照順時針的方向查找存儲節(jié)點(diǎn),即從數(shù)據(jù)映射在環(huán)上的位置開始,順時針方向找到的第一個存儲節(jié)點(diǎn),那么他就存儲在這個節(jié)點(diǎn)上。

我們使用一致性哈希算法來存儲我們的數(shù)據(jù),我畫了一張圖來模擬一致性哈希算法可能出現(xiàn)的結(jié)果:

一致性算法模擬存儲圖

我們先來解讀一下這張圖,按照一致性哈希算法的規(guī)則,數(shù)據(jù)沿著順時針的方向查找數(shù)據(jù),那么 id=4 的數(shù)據(jù)存放在 server1 服務(wù)器,id=2 的數(shù)據(jù)存放在服務(wù)器 server2 上,id=3、id=1、id=5、id=6 的數(shù)據(jù)都存放在服務(wù)器 server3 上,如果你比較敏感的話,也許你就會發(fā)現(xiàn)一致性哈希算法的不足之處, 從圖中可以看出,我們六條數(shù)據(jù)分布不均勻,并不是每臺服務(wù)器存儲 2 條數(shù)據(jù),而且差距好像還有點(diǎn)大,這里我們就要來說一說一致性哈希算法的缺點(diǎn):一致性哈希算法會會造成數(shù)據(jù)分布不均勻的問題或者叫做數(shù)據(jù)傾斜問題,就像我們圖中那樣,數(shù)據(jù)分布不均勻可能會造成某一個節(jié)點(diǎn)的負(fù)載過大,從而宕機(jī)。造成數(shù)據(jù)分布不均勻有以下兩種情況:

  • 第一:哈希函數(shù)的原因,經(jīng)過哈希函數(shù)之后服務(wù)器在哈希環(huán)上的分布不均勻,服務(wù)器之間的間距不相等,這樣就會導(dǎo)致數(shù)據(jù)不均勻。
  • 第二:某服務(wù)器宕機(jī)了,后繼節(jié)點(diǎn)就需要承受原本屬于宕機(jī)機(jī)器的數(shù)據(jù),這樣也會造成數(shù)據(jù)不均勻。

前面我們提到過一致性哈希算法解決了哈希算法中擴(kuò)展性差的問題,這個怎么理解呢?我們來看看,在一致性哈希算法中當(dāng)有存儲節(jié)點(diǎn)加入或者退出時,只會影響應(yīng)該該節(jié)點(diǎn)的后繼節(jié)點(diǎn),舉個例子說明一下,例如我們要在服務(wù)器server3 和服務(wù) server2 之間加入了一個服務(wù)器存儲節(jié)點(diǎn) server4,只會對服務(wù)器server3 造成影響,原本存儲到服務(wù)器server3 上的數(shù)據(jù)有一部分會落入到服務(wù)器 server4 上,對服務(wù)器 server1 和 server2 并沒有任何影響,這樣就不會進(jìn)行大量的數(shù)據(jù)遷移,擴(kuò)展性就變強(qiáng)了。

帶有限負(fù)載的一致性哈希算法

因為一致性哈希算法的數(shù)據(jù)分布不均勻的問題,Google 在 2017 年提出了帶有限負(fù)載的一致性哈希算法來解決這個問題,帶有限負(fù)載的一致性哈希算法思想比較簡單,給每個存儲節(jié)點(diǎn)設(shè)置了一個存儲上限值來控制存儲節(jié)點(diǎn)添加或移除造成的數(shù)據(jù)不均勻,當(dāng)數(shù)據(jù)按照一致性哈希算法找到相應(yīng)的存儲節(jié)點(diǎn)時,要先判斷該存儲節(jié)點(diǎn)是否達(dá)到了存儲上限;如果已經(jīng)達(dá)到了上限,則需要繼續(xù)尋找該存儲節(jié)點(diǎn)順時針方向之后的節(jié)點(diǎn)進(jìn)行存儲。

我們利用帶有限負(fù)載的一致性哈希算法來改進(jìn)上面的數(shù)據(jù)存儲,我們限定每臺服務(wù)器節(jié)點(diǎn)存儲的數(shù)據(jù)上限為 2 ,數(shù)據(jù)插入的順序就按照 ID 大小的順序,同樣我也畫了一張模擬圖:

帶有限負(fù)載的一致性哈希算法

一起來分析一下這張圖,因為我們的添加順序是按照 id 大小的順序,所以前四個數(shù)據(jù)都沒有問題,這時候的服務(wù)器都沒有超過最高負(fù)載數(shù)量,id=5 的數(shù)據(jù)落在了服務(wù)器server2 和服務(wù)器server3 之間,本應(yīng)該是存儲在服務(wù)器server3 上,但是由于此時的服務(wù)器server3 上已經(jīng)存儲了 id=1、id=3 的數(shù)據(jù)達(dá)到了最高限定,因此 id=5 的數(shù)據(jù)會沿著順時針的方向繼續(xù)往下尋找服務(wù)器,下一個服務(wù)器就是server1,此時的服務(wù)器server1 就存儲了 id=4 的數(shù)據(jù)并沒有達(dá)到上限,所以 id=5 的數(shù)據(jù)就會存儲在服務(wù)器server1,id=6 的數(shù)據(jù)同樣的道理。這樣就利用帶有限負(fù)載的一致性哈希算法解決了一致性哈希算法中數(shù)據(jù)分布不均勻的問題。

帶虛擬節(jié)點(diǎn)的一致性哈希算法

帶有限負(fù)載的一致性哈希算法也有一個問題,那就是每臺服務(wù)器的性能配置可能存在不一樣,如果規(guī)定數(shù)量過小的話,對于配置高的服務(wù)器來說有點(diǎn)浪費(fèi),這是因為服務(wù)器之間可能存在差異,叫做服務(wù)器之間的異構(gòu)性,為了解決服務(wù)器之間的異構(gòu)性問題,引入了一種叫做帶虛擬節(jié)點(diǎn)的一致性哈希算法,帶虛擬節(jié)點(diǎn)的一致性哈希算法核心思想是:根據(jù)每個節(jié)點(diǎn)的性能為每個節(jié)點(diǎn)劃分不同數(shù)量的虛擬節(jié)點(diǎn),并將這些虛擬節(jié)點(diǎn)映射到哈希環(huán)中,然后再按照一致性哈希算法進(jìn)行數(shù)據(jù)映射和存儲。

為了演示帶虛擬節(jié)點(diǎn)的一致性哈希算法,我們先做一個假設(shè)服務(wù)器server3是配置最差的,所以我們以服務(wù)器server3 為基準(zhǔn),服務(wù)器server2 是服務(wù)器server3 的兩倍,服務(wù)器server1 是服務(wù)器server3 的三倍,有了這個前提之后,我們就可以來建立虛擬節(jié)點(diǎn),我們假設(shè)服務(wù)器server3 的虛擬節(jié)點(diǎn)為服務(wù)器server3_1,服務(wù)器server2 就有兩個虛擬節(jié)點(diǎn)服務(wù)器server2_1、服務(wù)器server2_2,服務(wù)器server1 有三個虛擬節(jié)點(diǎn) 服務(wù)器server1_1、服務(wù)器server1_2、服務(wù)器server1_3。我還是跟前面一樣畫了一張模擬圖:

落到虛擬節(jié)點(diǎn)上的數(shù)據(jù)都會存到對應(yīng)的物理服務(wù)器上,所以通過帶虛擬節(jié)點(diǎn)的一致性哈希算法后,數(shù)據(jù)存儲結(jié)果為:數(shù)據(jù)id=2、id=3、id=5 的數(shù)據(jù)都會存儲到服務(wù)器server1 上,id=1 的數(shù)據(jù)將會存儲到服務(wù)器server2 上,數(shù)據(jù) id=4、id=6 都會存放到服務(wù)器server3上。

虛擬節(jié)點(diǎn)可以讓配置好的服務(wù)器存儲更多的數(shù)據(jù),這樣就解決了系統(tǒng)異構(gòu)性的問題,同時由于大量的虛擬節(jié)點(diǎn)的存在 在數(shù)據(jù)遷移時數(shù)據(jù)會落到不同的物理機(jī)上,這樣就減小了數(shù)據(jù)遷移時某臺服務(wù)器的分擔(dān)壓力,能夠保證系統(tǒng)的穩(wěn)定性。

虛擬槽分區(qū)

虛擬槽分區(qū)是 redis cluster 中默認(rèn)的數(shù)據(jù)分布技術(shù),虛擬槽分區(qū)巧妙地使用了哈??臻g,使用分散度良好的哈希函數(shù)把所有數(shù)據(jù)映射到一個固定范圍的整數(shù)集合中,這個整數(shù)定義為槽(slot),而且這個槽的個數(shù)一般遠(yuǎn)遠(yuǎn)的大于節(jié)點(diǎn)數(shù)。

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

虛擬槽分區(qū)解耦了數(shù)據(jù)與節(jié)點(diǎn)的關(guān)系,通過引入槽,讓槽成為集群內(nèi)數(shù)據(jù)管理和遷移的基本單位,簡化了節(jié)點(diǎn)擴(kuò)容和收縮難度,你只需要關(guān)注數(shù)據(jù)在哪個槽,并不需要關(guān)心數(shù)據(jù)在哪個節(jié)點(diǎn)上。所以虛擬槽分區(qū)可以說比較好的兼容了數(shù)據(jù)均勻分布和擴(kuò)展性的問題。

以上就是我要分享關(guān)于集群中數(shù)據(jù)分布的技術(shù),希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,感謝大家的支持!

 

責(zé)任編輯:華軒 來源: 平頭哥的技術(shù)博文
相關(guān)推薦

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2024-04-08 11:25:10

Redis緩存策略

2023-12-12 07:13:39

雪花算法分布式ID

2022-03-08 16:10:38

Redis事務(wù)機(jī)制

2022-05-12 23:19:15

Redis內(nèi)存碎片處理

2023-09-20 23:01:03

Twitter算法

2020-01-17 09:07:14

分布式系統(tǒng)網(wǎng)絡(luò)

2023-03-06 21:23:23

Redis數(shù)據(jù)庫

2019-12-12 14:52:10

數(shù)據(jù)庫腳本

2021-01-04 08:09:07

Linux內(nèi)核Watchdog

2020-07-16 14:40:23

大數(shù)據(jù)計算框架

2022-05-18 16:35:43

Redis內(nèi)存運(yùn)維

2021-08-11 09:37:11

Redis持久化磁盤

2020-07-14 08:53:43

Redis數(shù)據(jù)存儲

2020-05-09 14:20:11

信息安全加密

2019-12-02 16:23:03

Python編程語言“垃圾”回收

2022-08-30 07:39:57

C++namespace隔離

2020-12-11 11:11:44

原子類JavaCAS

2018-04-25 09:01:02

2021-01-28 22:31:33

分組密碼算法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號