Redis专题-集群模式
在redis持久化方式一文中,我們已經提到為了防止數據丟失,redis提供了RDB和AOF兩種方式持久化數據,將內存的數據持久化到磁盤上。但是當出現服務器出現故障,比如服務磁盤壞掉導致數據不可恢復時。那又該怎么辦呢?這時候就需要進行數據備份,將數據存儲在多臺服務器上。為了解決以上這個問題,現在就讓我來跟大家聊一聊redis的三種集群模式-主從模式,哨兵模式和redis-clust模式都是進行處理的以及各自的特點。
1.主從模式
主從模式主要原理是主從復制,當然這三種方式都是采用主從復制。Redis雖然讀取寫入的速度都特別快,但是也會產生性能瓶頸,特別是在讀壓力上。為了分擔壓力,Redis支持主從復制。Redis的主從結構可以是一主一從,一主多從或級聯結構,復制類型可以根據是否是全量而分為全量同步和增量同步。
1.1 主從模式結構圖
以上為主從模式(一主多從)的簡單架構圖。主從模式里使用一個redis實例作為主機(master),用來支持數據的寫入和讀取操作,其余多個實例作為備份機(slave),支持讀取及master的數據同步,在整個架構里,master和slave實例里的數據完全一致。
1.2 主從模式原理
主從模式的數據存儲需要在不同時機段進行不同的賦值操作,這里主要有類:全量同步和增量同步。
1.2.1 全量同步
Redis全量同步復制一般發生在slave的初始階段,這時slave需要將master上的數據都復制一份。以下是全量同步的大致流程圖:
具體的過程如下:
1.2.1 增量同步
增量復制實際上就是在從節點初始化完成后開始正常工作時主節點發生寫操作同步到從節點的過程。增量復制的過程主要是主節點每執行一個寫命令就會向從節點發送相同的寫命令,從節點接受并執行寫命令,從而保持主從一致。
所以redis的主從同步策略是這樣的:主從同步剛連接的時候進行全量同步;全量同步結束后開始增量同步。當前然如果有需要的話,從節點在任何時候都可以發起全量同步,其主要策略就是無論如何首先會嘗試進行增量同步,如果不成功,則會要求從節點進行全量同步,之后再進行增量同步。
1.3 主從模式特點
主從模式具有以下特點:
- 采用異步復制,可以一主多從,從還可以連接其他的從;
- 主從復制對于master來說是非阻塞的,也就是說slave在進行主從復制的過程中,master依然可以處理請求;
- 主從復制對于slave來說也是非阻塞的,也就是說slave在進行主從復制的過程中也可以接受外界的查詢請求,只不過這時候返回的數據不一定是正確的。為了避免這種情況發生,可以在slave的配置文件中配置,在同步過程中阻止查詢;
主從模式提高了Redis服務的擴展性,避免單節點問題,另外也為數據備份冗余提供了一種解決方案。為了降低主redis服務器寫磁盤壓力帶來的開銷,可以配置讓主redis不再將數據持久化到磁盤,而是通過連接讓一個配置的從redis服務器及時的將相關數據持久化到磁盤,不過這樣會存在一個問題,就是主redis服務器一旦重啟,因為主redis服務器數據為空,這時候通過主從同步可能導致從redis服務器上的數據也被清空。
2.哨兵模式
主從模式中,每個客戶端連接redis實例時都指定了ip和端口號。如果所連接的redis實例因為故障下線了,則無法通知客戶端連接其他客戶端地址,于是redis集群迎來了哨兵模式,它可以監控Redis系統的運行狀態,并做相應的響應。
2.1 哨兵模式架構圖
哨兵模式基本架構圖如圖所示:
和主從模式不一樣的是,哨兵模式中增加了獨立進程(即哨兵)來監控集群中的一舉一動??蛻舳嗽谶B接集群時,首先連接哨兵,通過哨兵查詢主節點的地址,然后再去連接主節點進行數據交互。哨兵的功能主要有兩點:
通過哨兵可以管理多個Redis服務器,它的任務主要有以下三個:
2.2 哨兵模式原理
小兵模式是基于以上三個任務來完成對各節點的監控和發現的,接下來從每個任務出發來分析一下基本原理。
(1)監控
每隔1秒每個哨兵會向主節點、從節點及其余哨兵節點發送一次ping命令做一次心跳檢測。每個哨兵節點每10秒會向主節點和從節點發送info命令獲取最新拓撲結構圖,哨兵配置時只要配置對主節點的監控即可,通過向主節點發送info,獲取從節點的信息,并當有新的從節點加入時可以馬上感知到。
(2)提醒
每個哨兵節點每隔2秒會向redis數據節點的指定頻道上發送該哨兵節點對于主節點的判斷以及當前哨兵節點的信息,同時每個哨兵節點也會訂閱該頻道,來了解其它哨兵節點的信息及對主節點的判斷。這里說明兩個詞,一個是主觀下線,一個是客觀下線。
主觀下線:哨兵節點每隔1秒對主節點和從節點、其它哨兵節點發送ping做心跳檢測,當這些心跳檢測時間超過down-after-milliseconds時,哨兵節點則認為該節點錯誤或下線,這叫主觀下線。這可能會存在錯誤的判斷;
客觀下線:當主觀下線的節點是主節點時,此時該哨兵節點會通過指令sentinel is-masterdown-by-addr尋求其它哨兵節點對主節點的判斷,當超過quorum(法定人數)個數,此時哨兵節點則認為該主節點確實有問題,這樣就客觀下線了,大部分哨兵節點都同意下線操作,也就說是客觀下線。
當某個節點被標記為客觀下線時,就需要重新選舉領導者,redis采用Raft算法實現選舉機制,選出一個哨兵節點(哨兵也有主節點)來完成轉移和通知,領導者哨兵選舉流程如下:
(3)故障遷移
2.3 哨兵模式特點
哨兵模式的出現雖然解決了主從模式中master節點宕機不能自主切換(即高可用)的問題,但是依然存在一些問題:
(1)主從服務器的數據要經常進行主從復制,這樣會造成性能下降;
(2)當主服務器宕機后,從服務器切換成主服務器的那段時間,服務是不可用的;
(3)隨著業務的逐漸增長,不可避免需要對當前業務進行擴容。擴容又分為水平擴容和垂直擴容,垂直擴容指通過增加master內存來增加容量;水平擴容指通過增加節點來進行擴容,即在當前基礎上再增加一個master節點。雖然垂直擴容方式很便捷,不需要添加多余的節點,但是機器的容量是有限的,最終還是需要通過水平擴容方式來解決。而水平擴容涉及到數據的遷移,且遷移過程中又要保證服務的可用性。因此,數據能不遷移就盡量不要遷移。顯然,哨兵模式無法滿足這種情形,redis cluster應運而生。
3.redis-cluster模式
Redis在3.0版本開始正式引用集群特性,Redis集群是一個分布式,高容錯的內存K/V系統。
3.1 redis-cluster模式結構圖
redis cluster模式采用了無中心節點的方式來實現,每個主節點都會與其它主節點保持連接。節點間通過gossip協議交換彼此的信息,同時每個主節點又有一個或多個從節點。
3.2 redis-cluster模式原理
3.2.1 數據存儲
Redis Cluster中有一個16384長度的槽的概念,他們的編號為0、1、2、3……16382、16383。這個槽是一個虛擬的槽,并不是真正存在的。正常工作的時候,Redis Cluster中的每個Master節點都會負責一部分的槽,當有某個key被映射到某個Master負責的槽,那么這個Master負責為這個key提供服務,至于哪個Master節點負責哪個槽,這是可以由用戶指定的,也可以在初始化的時候自動生成(redis-trib.rb腳本)。如下所示:
群中的每個節點至少一個備用的redis服務,這個集群就不會那么容易掛掉。這里設置的是Master1負責0-5460號哈希槽,Master2負責5461-10922號哈希槽,Master3負責10922~16383號哈希槽,前面說過了大家可以依據自己的設定自行進行調整,每個節點會保存一份數據分布表,節點會將自己的槽信息發送給其他節點,節點間不停的傳遞數據分布表。需要注意的是,在Redis Cluster中,只有Master才擁有槽的所有權,如果是某個Master的slave,這個slave只負責槽的使用,但是沒有所有權。
了解了哈希槽以后,那么Redis集群是怎么依據這些存儲數據的呢?當我們的存取的key到達的時候,redis會根據特定算法得出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作。
3.2.2 故障處理
redis cluster中主節點故障處理方式與哨兵模式較為相像,當約定時間內某節點無法與集群中的另一個節點順利完成ping消息通信時,則將該節點標記為主觀下線狀態,同時將這個信息向整個集群廣播。如果一個節點收到某個節點失聯的數量達到了集群的大多數時,那么將該節點標記為客觀下線狀態,并向集群廣播下線節點的fail消息。然后立即對該故障節點進行主從切換。等到原來的主節點恢復后,會自動成為新主節點的從節點。如果主節點沒有從節點,那么當它發生故障時,集群就將處于不可用狀態。需要注意的是如果有一半以上的節點去ping一個節點的時候沒有回應,集群就認為這個節點宕機了,然后去連接它的備用節點。如果某個節點和所有從節點全部掛掉,我們集群就進入faill狀態。還有就是如果有一半以上的主節點宕機,那么我們集群同樣進入faill狀態。
3.2.3 擴容問題
在哨兵模式中我們在擴容的時候遇到了問題,那么cluster中我們如何動態上線某個節點呢?當集群中加入某個節點時,哈希槽又是如何來進行分配的?當集群中加入新節點時,會與集群中的某個節點進行握手,該節點會把集群內的其它節點信息通過gossip協議發送給新節點,新節點與這些節點完成握手后加入到集群中,然后集群中的節點會各取一部分哈希槽分配給新節點。比如我們此時要新增一個節點Master4,如下圖:
我們將Master1,Master2,Master3的部分槽重新分配給Master4。當集群中要刪除節點時,只需要將節點中的所有哈希槽移動到其它節點,然后再移除空白(不包含任何哈希槽)的節點就可以了。
3.3 redis-cluster模式特點
Redis集群有以下幾個重要的特征::
- Redis集群的分片特征在于將空間拆分為16384個槽位,某一個節點負責其中一些槽位;
- Redis集群提供一定程度的可用性,可以在某個節點宕機或者不可達的情況繼續處理命令;
- Redis集群不存在中心節點或代理節點,集群的其中一個最重要的設計目標是達到線性可擴展性。
猜你感興趣:
Redis專題-集群模式
Redis專題-持久化方式
Redis專題-底層數據結構與使用場景
Redis專題-緩存穿透、緩存雪崩、緩存擊穿
更多文章請點擊:更多…
總結
以上是生活随笔為你收集整理的Redis专题-集群模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis专题-持久化方式
- 下一篇: MYSQL专题-绝对实用的MYSQL优化