Redis集群都有哪些模式
redis的多機數(shù)據(jù)庫實現(xiàn),主要分為以下幾種:
1,主從復制
2,哨兵模式
3,Redis官方提供的Cluster集群模式(服務(wù)端)
4,Jedis sharding集群(客戶端sharding)
5, 利用中間件代理,比如codis等
其中前三個為服務(wù)器端方案 后兩個為客戶端分區(qū)方案,類似于分表分庫方案
主從復制(Master-Slave Replication):
實現(xiàn)主從復制(Master-Slave Replication)的工作原理:Slave從節(jié)點服務(wù)啟動并連接到Master之后,它將主動發(fā)送一個SYNC命令。Master服務(wù)主節(jié)點收到同步命令后將啟動后臺存盤進程,同時收集所有接收到的用于修改數(shù)據(jù)集的命令,在后臺進程執(zhí)行完畢后,Master將傳送整個數(shù)據(jù)庫文件到Slave,以完成一次完全同步。而Slave從節(jié)點服務(wù)在接收到數(shù)據(jù)庫文件數(shù)據(jù)之后將其存盤并加載到內(nèi)存中。此后,Master主節(jié)點繼續(xù)將所有已經(jīng)收集到的修改命令,和新的修改命令依次傳送給Slaves,Slave將在本次執(zhí)行這些數(shù)據(jù)修改命令,從而達到最終的數(shù)據(jù)同步。
如果Master和Slave之間的鏈接出現(xiàn)斷連現(xiàn)象,Slave可以自動重連Master,但是在連接成功之后,一次完全同步將被自動執(zhí)行。
主從模式的優(yōu)缺點
優(yōu)點:
- 同一個Master可以同步多個Slaves。
- Slave同樣可以接受其它Slaves的連接和同步請求,這樣可以有效的分載Master的同步壓力。因此我們可以將Redis的Replication架構(gòu)視為圖結(jié)構(gòu)。
- Master Server是以非阻塞的方式為Slaves提供服務(wù)。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求。
- Slave Server同樣是以非阻塞的方式完成數(shù)據(jù)同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的數(shù)據(jù)
- 為了分載Master的讀操作壓力,Slave服務(wù)器可以為客戶端提供只讀操作的服務(wù),寫服務(wù)仍然必須由Master來完成。即便如此,系統(tǒng)的伸縮性還是得到了很大的提高。
- Master可以將數(shù)據(jù)保存操作交給Slaves完成,從而避免了在Master中要有獨立的進程來完成此操作。
- 支持主從復制,主機會自動將數(shù)據(jù)同步到從機,可以進行讀寫分離。
缺點:
- Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
- 主機宕機,宕機前有部分數(shù)據(jù)未能及時同步到從機,切換IP后還會引入數(shù)據(jù)不一致的問題,降低了系統(tǒng)的可用性。
- Redis的主從復制采用全量復制,復制過程中主機會fork出一個子進程對內(nèi)存做一份快照,并將子進程的內(nèi)存快照保存為文件發(fā)送給從機,這一過程需要確保主機有足夠多的空余內(nèi)存。若快照文件較大,對集群的服務(wù)能力會產(chǎn)生較大的影響,而且復制過程是在從機新加入集群或者從機和主機網(wǎng)絡(luò)斷開重連時都會進行,也就是網(wǎng)絡(luò)波動都會造成主機和從機間的一次全量的數(shù)據(jù)復制,這對實際的系統(tǒng)運營造成了不小的麻煩。
- Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。為避免這一問題,運維人員在系統(tǒng)上線時必須確保有足夠的空間,這對資源造成了很大的浪費。
其實redis的主從模式很簡單,在實際的生產(chǎn)環(huán)境中是很少使用的,我也不建議在實際的生產(chǎn)環(huán)境中使用主從模式來提供系統(tǒng)的高可用性,之所以不建議使用都是由它的缺點造成的,在數(shù)據(jù)量非常大的情況,或者對系統(tǒng)的高可用性要求很高的情況下,主從模式也是不穩(wěn)定的。
哨兵模式:
該模式是從Redis的2.6版本開始提供的,但是當時這個版本的模式是不穩(wěn)定的,直到Redis的2.8版本以后,這個哨兵模式才穩(wěn)定下來,無論是主從模式,還是哨兵模式,這兩個模式都有一個問題,不能水平擴容,并且這兩個模式的高可用特性都會受到Master主節(jié)點內(nèi)存的限制。
Sentinel(哨兵)進程是用于監(jiān)控redis集群中Master主服務(wù)器工作的狀態(tài),在Master主服務(wù)器發(fā)生故障的時候,可以實現(xiàn)Master和Slave服務(wù)器的切換,保證系統(tǒng)的高可用。
Sentinel(哨兵)進程的作用
- 監(jiān)控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運作正常。
- 提醒(Notification):當被監(jiān)控的某個Redis節(jié)點出現(xiàn)問題時, 哨兵(sentinel) 可以通過 API 向管理員或者其他應用程序發(fā)送通知。
- 自動故障遷移(Automatic failover):當一個Master不能正常工作時,哨兵(sentinel) 會開始一次自動故障遷移操作,它會將失效Master的其中一個Slave升級為新的Master, 并讓失效Master的其他Slave改為復制新的Master;當客戶端試圖連接失效的Master時,集群也會向客戶端返回新Master的地址,使得集群可以使用現(xiàn)在的Master替換失效Master。Master和Slave服務(wù)器切換后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的內(nèi)容都會發(fā)生相應的改變,即,Master主服務(wù)器的redis.conf配置文件中會多一行slaveof的配置,sentinel.conf的監(jiān)控目標會隨之調(diào)換。
Sentinel(哨兵)進程的工作方式
- 每個Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集群中的Master主服務(wù)器,Slave從服務(wù)器以及其他Sentinel(哨兵)進程發(fā)送一個 PING 命令。
- 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記為主觀下線(SDOWN)
- 如果一個Master主服務(wù)器被標記為主觀下線(SDOWN),則正在監(jiān)視這個Master主服務(wù)器的所有 Sentinel(哨兵)進程要以每秒一次的頻率確認Master主服務(wù)器的確進入了主觀下線狀態(tài)
- 當有足夠數(shù)量的 Sentinel(哨兵)進程(大于等于配置文件指定的值)在指定的時間范圍內(nèi)確認Master主服務(wù)器進入了主觀下線狀態(tài)(SDOWN), 則Master主服務(wù)器會被標記為客觀下線(ODOWN)
- 在一般情況下, 每個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集群中的所有Master主服務(wù)器、Slave從服務(wù)器發(fā)送 INFO 命令。
- 當Master主服務(wù)器被 Sentinel(哨兵)進程標記為客觀下線(ODOWN)時,Sentinel(哨兵)進程向下線的 Master主服務(wù)器的所有 Slave從服務(wù)器發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
- 若沒有足夠數(shù)量的 Sentinel(哨兵)進程同意 Master主服務(wù)器下線, Master主服務(wù)器的客觀下線狀態(tài)就會被移除。若 Master主服務(wù)器重新向 Sentinel(哨兵)進程發(fā)送 PING 命令返回有效回復,Master主服務(wù)器的主觀下線狀態(tài)就會被移除。
哨兵模式的優(yōu)缺點
優(yōu)點:
- 哨兵集群模式是基于主從模式的,所有主從的優(yōu)點,哨兵模式同樣具有。
- 主從可以切換,故障可以轉(zhuǎn)移,系統(tǒng)可用性更好。
- 哨兵模式是主從模式的升級,系統(tǒng)更健壯,可用性更高。
缺點:
- Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。為避免這一問題,運維人員在系統(tǒng)上線時必須確保有足夠的空間,這對資源造成了很大的浪費。
- 配置復雜
Redis官方 Cluster集群模式
Redis Cluster是一種服務(wù)器Sharding技術(shù),3.0版本開始正式提供。
集群通過分片來進行數(shù)據(jù)共享,并提供復制和故障轉(zhuǎn)移功能。一個Redis集群通常由多個節(jié)點組成;最初,每個節(jié)點都是獨立的,需要將獨立的節(jié)點連接起來才能形成可工作的集群。
Redis中的集群分為主節(jié)點和從節(jié)點。其中主節(jié)點用于處理槽;而從節(jié)點用于復制某個主節(jié)點,并在被復制的主節(jié)點下線時,代替下線的主節(jié)點繼續(xù)處理命令請求。
集群模式將在下一篇文章詳細講解。
Jedis sharding集群
這是一個客戶端分區(qū)方案
Redis Sharding可以說是在Redis cluster出來之前業(yè)界普遍的采用方式,客戶端就已經(jīng)決定數(shù)據(jù)會被 存儲到哪個redis 節(jié)點或者從哪個 redis 節(jié)點 讀取數(shù)據(jù)。其主要思想是采用 哈希算法 將 Redis 數(shù)據(jù)的 key 進行散列,通過 hash 函數(shù),特定的 key會 映射 到特定的 Redis 節(jié)點上。

慶幸的是,Java Redis客戶端驅(qū)動Jedis已支持Redis Sharding功能,即ShardedJedis以及結(jié)合緩存池的ShardedJedisPool
Jedis的Redis Sharding實現(xiàn)具有如下特點:
- 采用一致性哈希算法,將key和節(jié)點name同時hashing,然后進行映射匹配,采用的算法是MURMUR_HASH。采用一致性哈希而不是采用簡單類似哈希求模映射的主要原因是當增加或減少節(jié)點時,不會產(chǎn)生由于重新匹配造成的rehashing。一致性哈希只影響相鄰節(jié)點key分配,影響量小。
- 為了避免一致性哈希只影響相鄰節(jié)點造成節(jié)點分配壓力,ShardedJedis會對每個Redis節(jié)點根據(jù)名字(沒有,Jedis會賦予缺省名字)會虛擬化出160個虛擬節(jié)點進行散列。根據(jù)權(quán)重weight,也可虛擬化出160倍數(shù)的虛擬節(jié)點。用虛擬節(jié)點做映射匹配,可以在增加或減少Redis節(jié)點時,key在各Redis節(jié)點移動再分配更均勻,而不是只有相鄰節(jié)點受影響。
- ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,這樣通過合理命名key,可以將一組相關(guān)聯(lián)的key放入同一個Redis節(jié)點,這在避免跨節(jié)點訪問相關(guān)數(shù)據(jù)時很重要。
當然,Redis Sharding這種輕量靈活方式必然在集群其它能力方面做出妥協(xié)。比如擴容,當想要增加Redis節(jié)點時,盡管采用一致性哈希,畢竟還是會有key匹配不到而丟失,這時需要鍵值遷移。
作為輕量級客戶端sharding,處理Redis鍵值遷移是不現(xiàn)實的,這就要求應用層面允許Redis中數(shù)據(jù)丟失或從后端數(shù)據(jù)庫重新加載數(shù)據(jù)。但有些時候,擊穿緩存層,直接訪問數(shù)據(jù)庫層,會對系統(tǒng)訪問造成很大壓力。
利用中間件代理
客戶端發(fā)送請求到一個 代理組件,代理解析客戶端的數(shù)據(jù),并將請求轉(zhuǎn)發(fā)至正確的節(jié)點,最后將結(jié)果回復給客戶端。

優(yōu)點:簡化 客戶端 的分布式邏輯,客戶端 透明接入,切換成本低,代理的 轉(zhuǎn)發(fā) 和 存儲 分離。
缺點:多了一層 代理層,加重了 架構(gòu)部署復雜度 和 性能損耗。