溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis哈希分片原理是什么

發(fā)布時(shí)間:2021-11-10 15:10:01 來源:億速云 閱讀:159 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫

本篇內(nèi)容介紹了“Redis哈希分片原理是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

集群分片模式

如果Redis只用復(fù)制功能做主從,那么當(dāng)數(shù)據(jù)量巨大的情況下,單機(jī)情況下可能已經(jīng)承受不下一份數(shù)據(jù),更不用說是主從都要各自保存一份完整的數(shù)據(jù)。在這種情況下,數(shù)據(jù)分片是一個(gè)非常好的解決辦法。

Redis的Cluster正是用于解決該問題。它主要提供兩個(gè)功能:

  1. 自動(dòng)對(duì)數(shù)據(jù)分片,落到各個(gè)節(jié)點(diǎn)上

  2. 即使集群部分節(jié)點(diǎn)失效或者連接不上,依然可以繼續(xù)處理命令

對(duì)于第二點(diǎn),它的功能有點(diǎn)類似于Sentienl的故障轉(zhuǎn)移(可以了解下之前Sentinel的文章),在這里不細(xì)說。下面詳細(xì)了解下Redis的槽位分片原理,在此之前,先了解下分布式簡單哈希算法和一致性哈希算法,以幫助理解槽位的作用。

簡單哈希算法

假設(shè)有三臺(tái)機(jī),數(shù)據(jù)落在哪臺(tái)機(jī)的算法為

  c = Hash(key) % 3

例如key A的哈希值為4,4%3=1,則落在第二臺(tái)機(jī)。Key ABC哈希值為11,11%3=2,則落在第三臺(tái)機(jī)上。

利用這樣的算法,假設(shè)現(xiàn)在數(shù)據(jù)量太大了,需要增加一臺(tái)機(jī)器。A原本落在第二臺(tái)上,現(xiàn)在根據(jù)算法4%4=0,落到了第一臺(tái)機(jī)器上了,但是第一臺(tái)機(jī)器上根本沒有A的值。這樣的算法會(huì)導(dǎo)致增加機(jī)器或減少機(jī)器的時(shí)候,引起大量的緩存穿透,造成雪崩。

一致性哈希算法

在1997年,麻省理工學(xué)院的Karger等人提出了一致性哈希算法,為的就是解決分布式緩存的問題。

一致性哈希算法中,整個(gè)哈希空間是一個(gè)虛擬圓環(huán)
Redis哈希分片原理是什么

假設(shè)有四個(gè)節(jié)點(diǎn)Node A、B、C、D,經(jīng)過ip地址的哈希計(jì)算,它們的位置如下
Redis哈希分片原理是什么

有4個(gè)存儲(chǔ)對(duì)象Object A、B、C、D,經(jīng)過對(duì)Key的哈希計(jì)算后,它們的位置如下
Redis哈希分片原理是什么
對(duì)于各個(gè)Object,它所真正的存儲(chǔ)位置是按順時(shí)針找到的第一個(gè)存儲(chǔ)節(jié)點(diǎn)。例如Object A順時(shí)針找到的第一個(gè)節(jié)點(diǎn)是Node A,所以Node A負(fù)責(zé)存儲(chǔ)Object A,Object B存儲(chǔ)在Node B。

一致性哈希算法大概如此,那么它的容錯(cuò)性擴(kuò)展性如何呢?

假設(shè)Node C節(jié)點(diǎn)掛掉了,Object C的存儲(chǔ)丟失,那么它順時(shí)針找到的最新節(jié)點(diǎn)是Node D。也就是說Node C掛掉了,受影響僅僅包括Node B到Node C區(qū)間的數(shù)據(jù),并且這些數(shù)據(jù)會(huì)轉(zhuǎn)移到Node D進(jìn)行存儲(chǔ)。
Redis哈希分片原理是什么

同理,假設(shè)現(xiàn)在數(shù)據(jù)量大了,需要增加一臺(tái)節(jié)點(diǎn)Node X。Node X的位置在Node B到Node C直接,那么受到影響的僅僅是Node B到Node X間的數(shù)據(jù),它們要重新落到Node X上。

所以一致性哈希算法對(duì)于容錯(cuò)性和擴(kuò)展性有非常好的支持。但一致性哈希算法也有一個(gè)嚴(yán)重的問題,就是數(shù)據(jù)傾斜。

如果在分片的集群中,節(jié)點(diǎn)太少,并且分布不均,一致性哈希算法就會(huì)出現(xiàn)部分節(jié)點(diǎn)數(shù)據(jù)太多,部分節(jié)點(diǎn)數(shù)據(jù)太少。也就是說無法控制節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù)的分配。如下圖,大部分?jǐn)?shù)據(jù)都在A上了,B的數(shù)據(jù)比較少。
Redis哈希分片原理是什么

哈希槽

Redis集群(Cluster)并沒有選用上面一致性哈希,而是采用了哈希槽(SLOT)的這種概念。主要的原因就是上面所說的,一致性哈希算法對(duì)于數(shù)據(jù)分布、節(jié)點(diǎn)位置的控制并不是很友好。

首先哈希槽其實(shí)是兩個(gè)概念,第一個(gè)是哈希算法。Redis Cluster的hash算法不是簡單的hash(),而是crc16算法,一種校驗(yàn)算法。

另外一個(gè)就是槽位的概念,空間分配的規(guī)則。其實(shí)哈希槽的本質(zhì)和一致性哈希算法非常相似,不同點(diǎn)就是對(duì)于哈??臻g的定義。一致性哈希的空間是一個(gè)圓環(huán),節(jié)點(diǎn)分布是基于圓環(huán)的,無法很好的控制數(shù)據(jù)分布。而Redis Cluster的槽位空間是自定義分配的,類似于Windows盤分區(qū)的概念。這種分區(qū)是可以自定義大小,自定義位置的。

Redis Cluster包含了16384個(gè)哈希槽,每個(gè)Key通過計(jì)算后都會(huì)落在具體一個(gè)槽位上,而這個(gè)槽位是屬于哪個(gè)存儲(chǔ)節(jié)點(diǎn)的,則由用戶自己定義分配。例如機(jī)器硬盤小的,可以分配少一點(diǎn)槽位,硬盤大的可以分配多一點(diǎn)。如果節(jié)點(diǎn)硬盤都差不多則可以平均分配。所以哈希槽這種概念很好地解決了一致性哈希的弊端。

另外在容錯(cuò)性擴(kuò)展性上,表象與一致性哈希一樣,都是對(duì)受影響的數(shù)據(jù)進(jìn)行轉(zhuǎn)移。而哈希槽本質(zhì)上是對(duì)槽位的轉(zhuǎn)移,把故障節(jié)點(diǎn)負(fù)責(zé)的槽位轉(zhuǎn)移到其他正常的節(jié)點(diǎn)上。擴(kuò)展節(jié)點(diǎn)也是一樣,把其他節(jié)點(diǎn)上的槽位轉(zhuǎn)移到新的節(jié)點(diǎn)上。

但一定要注意的是,對(duì)于槽位的轉(zhuǎn)移和分派,Redis集群是不會(huì)自動(dòng)進(jìn)行的,而是需要人工配置的。所以Redis集群的高可用是依賴于節(jié)點(diǎn)的主從復(fù)制與主從間的自動(dòng)故障轉(zhuǎn)移。

集群搭建

下面以最簡單的例子,拋開高可用主從復(fù)制級(jí)轉(zhuǎn)移的內(nèi)容,來重點(diǎn)介紹下Redis集群是如何搭建,槽位是如何分配的,以加深對(duì)Redis集群原理及概念的理解。

redis.conf配置

先找到redis.conf,啟用cluster功能。
Redis哈希分片原理是什么

cluster-enabled yes默認(rèn)是關(guān)閉的,要啟用cluster,讓redis成為集群的一部分,需要手動(dòng)打開才行。

然后配置cluster的配置文件
Redis哈希分片原理是什么
每一個(gè)cluster節(jié)點(diǎn)都有一個(gè)cluster的配置文件,這個(gè)文件主要用于記錄節(jié)點(diǎn)信息,用程序自動(dòng)生成和管理,不需要人工干預(yù)。唯一要注意的是,如果在同一臺(tái)機(jī)器上運(yùn)行多個(gè)節(jié)點(diǎn),需要修改這個(gè)配置為不同的名字。

本次為了方便搭建,所有Redis實(shí)例都在同一臺(tái)機(jī)器上,所以修改不同的cluster config名字后,復(fù)制三份redis.conf配置,以用于啟動(dòng)三個(gè)集群實(shí)例(cluster至少要三個(gè)主節(jié)點(diǎn)才能進(jìn)行)。

集群關(guān)聯(lián)

  > redis-server /usr/local/etc/redis/redis-6379.conf --port 6379 &
  > redis-server /usr/local/etc/redis/redis-6380.conf --port 6380 &
  > redis-server /usr/local/etc/redis/redis-6381.conf --port 6381 &

&符號(hào)的作用是讓命令在后臺(tái)執(zhí)行,但程序執(zhí)行的log依然會(huì)打印在console中。也可以通過配置redis.conf中deamonize yes,讓Redis在后臺(tái)運(yùn)行。

連上6379的Redis實(shí)例,然后通過cluster nodes查看集群范圍。
Redis哈希分片原理是什么
連上其他實(shí)例也是一樣,目前6379、6380、6381在各自的集群中,且集群只有它們自己一個(gè)。

在6379上,通過cluster meet命令,與6380、6381建立鏈接。

  127.0.0.1:6379> cluster meet 127.0.0.1 6380
  127.0.0.1:6379> cluster meet 127.0.0.1 6381

Redis哈希分片原理是什么
可以看到集群中已經(jīng)包含了6379、6380、6381三個(gè)節(jié)點(diǎn)了。登錄其他節(jié)點(diǎn)查看也是一樣的結(jié)果。即使6380與6381之間沒有直接手動(dòng)關(guān)聯(lián),但在集群中,節(jié)點(diǎn)一旦發(fā)現(xiàn)有未關(guān)聯(lián)的節(jié)點(diǎn),會(huì)自動(dòng)與之握手關(guān)聯(lián)。

槽位分配

通過cluster info命令查看集群的狀態(tài)
Redis哈希分片原理是什么
state的狀態(tài)是fail的,還沒啟用??聪鹿俜降恼f明
Redis哈希分片原理是什么
只有state為ok,節(jié)點(diǎn)才能接受請(qǐng)求。如果只要有一個(gè)槽位(slot)沒有分配,那么這個(gè)狀態(tài)就是fail。而一共需要分配16384槽位才能讓集群正常工作。

接下來給6379分配0~5000的槽位,給6380分配5001~10000的槽位,給6381分配10001~16383的槽位。

  > redis-cli -c -p 6379 cluster addslots {0..5000}
  > redis-cli -c -p 6380 cluster addslots {5001..10000}
  > redis-cli -c -p 6381 cluster addslots {10001..16383}

再看看cluster info
Redis哈希分片原理是什么
state已經(jīng)為ok,16384個(gè)槽位都已經(jīng)分配好了?,F(xiàn)在集群已經(jīng)可以正常工作了。

效果測試

隨便登上一個(gè)實(shí)例,記得加上參數(shù)-c,啟用集群模式的客戶端,否則無法正常運(yùn)行。

  redis-cli -c -p 6380

嘗試下set、get操作
Redis哈希分片原理是什么
可以看到,Redis集群會(huì)計(jì)算key落在哪個(gè)卡槽,然后會(huì)把命令轉(zhuǎn)發(fā)到負(fù)責(zé)該卡槽的節(jié)點(diǎn)上執(zhí)行。

利用cluster keyslot命令計(jì)算出key是在哪個(gè)槽位上,從而得出會(huì)跳轉(zhuǎn)到哪個(gè)節(jié)點(diǎn)上執(zhí)行。

“Redis哈希分片原理是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI