1谣蠢、集群分片模式
如果 redis 只用復(fù)制功能做主從滑潘,那么當(dāng)數(shù)據(jù)量巨大的情況下垢乙,單機(jī)情況下可能已經(jīng)承受不下一份數(shù)據(jù),更不用說是主從都要各自保存一份完整的數(shù)據(jù)语卤。在這種情況下追逮,數(shù)據(jù)分片是一個非常好的解決辦法。
redis 的 custer 正是用于解決該問題粹舵。它主要提供兩個功能:
1钮孵、自動對數(shù)據(jù)分片,落到各個節(jié)點上
2眼滤、即使集群部分節(jié)點失效或者連接不上巴席,依然可以繼續(xù)處理命令
對于第二點,它的功能有點類似于 sentienl 的故障轉(zhuǎn)移诅需,在這里不細(xì)說漾唉。下面詳細(xì)了解下 redis 的槽位分片原理,在此之前堰塌,先了解下分布式簡單哈希算法和一致性哈希算法毡证,以幫助理解槽位的作用。
2蔫仙、簡單哈希算法
假設(shè)有三臺機(jī),數(shù)據(jù)落在哪臺機(jī)的算法為:
c = Hash(key) % 3
例如 key A 的哈希值為4丐箩,4 % 3 = 1摇邦,則落在第二臺機(jī)。Key ABC 哈希值為11屎勘,11 % 3 = 2施籍,則落在第三臺機(jī)上。
利用這樣的算法概漱,假設(shè)現(xiàn)在數(shù)據(jù)量太大了丑慎,需要增加一臺機(jī)器。A 原本落在第二臺上,現(xiàn)在根據(jù)算法4 % 4 = 0竿裂,落到了第一臺機(jī)器上了玉吁,但是第一臺機(jī)器上根本沒有 A 的值。這樣的算法會導(dǎo)致增加機(jī)器或減少機(jī)器的時候腻异,引起大量的緩存穿透进副,造成雪崩。
3悔常、一致性哈希算法
在1997年影斑,麻省理工學(xué)院的 Karger 等人提出了一致性哈希算法,為的就是解決分布式緩存的問題机打。
在一致性哈希算法中矫户,整個哈希空間是一個虛擬圓環(huán)残邀。
假設(shè)有四個節(jié)點 Node A皆辽、B、C罐旗、D膳汪,經(jīng)過 ip 地址的哈希計算,它們的位置如下:
有4個存儲對象 Object A九秀、B遗嗽、C、D鼓蜒,經(jīng)過對 Key 的哈希計算后痹换,它們的位置如下:
?對于各個 Object,它所真正的存儲位置是按順時針找到的第一個存儲節(jié)點都弹。例如 Object A 順時針找到的第一個節(jié)點是 Node A娇豫,所以 Node A 負(fù)責(zé)存儲 Object A,Object B 存儲在 Node B畅厢。
一致性哈希算法大概如此冯痢,那么它的容錯性和擴(kuò)展性如何呢?
假設(shè) Node C 節(jié)點掛掉了框杜,Object C 的存儲丟失浦楣,那么它順時針找到的最新節(jié)點是 Node D。也就是說 Node C 掛掉了咪辱,受影響僅僅包括 Node B 到 Node C 區(qū)間的數(shù)據(jù)振劳,并且這些數(shù)據(jù)會轉(zhuǎn)移到 Node D 進(jìn)行存儲。
?同理油狂,假設(shè)現(xiàn)在數(shù)據(jù)量大了历恐,需要增加一臺節(jié)點 Node X寸癌。Node X 的位置在 Node B 到 Node C 直接,那么受到影響的僅僅是 Node B 到 Node X 間的數(shù)據(jù)弱贼,它們要重新落到 Node X 上蒸苇。
所以一致性哈希算法對于容錯性和擴(kuò)展性有非常好的支持。但一致性哈希算法也有一個嚴(yán)重的問題哮洽,就是數(shù)據(jù)傾斜填渠。
如果在分片的集群中,節(jié)點太少鸟辅,并且分布不均氛什,一致性哈希算法就會出現(xiàn)部分節(jié)點數(shù)據(jù)太多,部分節(jié)點數(shù)據(jù)太少匪凉。也就是說無法控制節(jié)點存儲數(shù)據(jù)的分配枪眉。如下圖,大部分?jǐn)?shù)據(jù)都在 A 上了再层,B 的數(shù)據(jù)比較少贸铜。
4、哈希槽
redis 集群(cluster)并沒有選用上面一致性哈希聂受,而是采用了哈希槽(slot)的這種概念蒿秦。主要的原因就是上面所說的,一致性哈希算法對于數(shù)據(jù)分布蛋济、節(jié)點位置的控制并不是很友好棍鳖。
首先哈希槽其實是兩個概念,第一個是哈希算法碗旅。redis cluster 的 hash 算法不是簡單的 hash()渡处,而是 crc16 算法,一種校驗算法祟辟。另外一個就是槽位的概念医瘫,空間分配的規(guī)則。其實哈希槽的本質(zhì)和一致性哈希算法非常相似旧困,不同點就是對于哈洗挤荩空間的定義。一致性哈希的空間是一個圓環(huán)吼具,節(jié)點分布是基于圓環(huán)的被芳,無法很好的控制數(shù)據(jù)分布。而 redis cluster 的槽位空間是自定義分配的馍悟,類似于 windows 盤分區(qū)的概念。這種分區(qū)是可以自定義大小剩晴,自定義位置的锣咒。
redis cluster 包含了16384個哈希槽侵状,每個 key 通過計算后都會落在具體一個槽位上,而這個槽位是屬于哪個存儲節(jié)點的毅整,則由用戶自己定義分配趣兄。例如機(jī)器硬盤小的,可以分配少一點槽位悼嫉,硬盤大的可以分配多一點艇潭。如果節(jié)點硬盤都差不多則可以平均分配。所以哈希槽這種概念很好地解決了一致性哈希的弊端戏蔑。
另外在容錯性和擴(kuò)展性上蹋凝,表象與一致性哈希一樣,都是對受影響的數(shù)據(jù)進(jìn)行轉(zhuǎn)移总棵。而哈希槽本質(zhì)上是對槽位的轉(zhuǎn)移鳍寂,把故障節(jié)點負(fù)責(zé)的槽位轉(zhuǎn)移到其他正常的節(jié)點上。擴(kuò)展節(jié)點也是一樣情龄,把其他節(jié)點上的槽位轉(zhuǎn)移到新的節(jié)點上迄汛。
但一定要注意的是,對于槽位的轉(zhuǎn)移和分派骤视,redis 集群是不會自動進(jìn)行的鞍爱,而是需要人工配置的。所以 redis 集群的高可用是依賴于節(jié)點的主從復(fù)制與主從間的自動故障轉(zhuǎn)移专酗。
轉(zhuǎn)自:https://zackku.com/redis-cluster/