有眼光啊,這麼多文章你點開了我,緣分,若是我沒猜錯的話,你是個有夢想的人,是個熱愛技術的人,咱們一塊兒手牽手撒?redis
咱們前面文章說的RDB和AOF是爲了解決單機redis的數據存儲問題,主從複製能夠實現數據冗餘,側重於解決數據的多機熱備份。可是主從複製中存在着一個問題就是故障恢復沒法自動化,而redis中的哨兵機制,基於Redis主從複製,主要做用即是解決主節點故障恢復的自動化問題,進一步提升系統的高可用性算法
Redis哨兵Sentinel,核心功能是主節點的自動故障轉移,管理多個Redis服務器,哨兵節點不存儲數據
持久化:持久化最容易理解,主要就是將數據備份,將數據備份到硬盤上,不會由於機器宕機停電等形成數據丟失服務器
主從複製:複製主要實現了多個機器的備份,以及對於讀操做的負載均衡和簡單的故障恢復(哨兵和集羣都是在複製的基礎上實現高可用的)存在缺陷:存儲能力受到單機限制,寫操做沒法負載均衡,故障沒法自動恢復網絡
哨兵模式:在複製的基礎上,哨兵實現了自動化的故障恢復。缺陷:寫操做沒法負載均衡;存儲能力受到單機的限制。架構
集羣:經過集羣,Redis解決了寫操做沒法負載均衡,以及存儲能力受到單機限制的問題,實現了較爲完善的高可用方案。負載均衡
提到哨兵,你們想到的是什麼呢?(科幻迷的我瞬間想到x戰警中無所不能,而後把變種人幹趴下的哨兵),在那裏邊是誰變異了,就幹掉誰異步
那麼Redis中哨兵是幹啥的呢?咱們上節說到主從架構是一主多從,主可寫可讀,從只能讀,那要是這個主節點宕機了,誰來對外提供寫服務呢?ide
你不就是主節點掛了嗎,我在衆多從節點中選出一個作爲新的主節點不就OK啦,對了,哨兵就是起這個做用的,那若是原來的主節點忽然好了,這時的主節點是原主節點仍是經過哨兵後選出的主節點呢?答案是經過哨兵選出的節點是主節點,也就意味着主節點宕機以後再次鏈接便失去了它的主節點的身份了server
咱們來看下Redis官方對哨兵功能的介紹:blog
集羣監控:監控Redis master主和slave從進程是否正常運行
消息通知:從若是Redis實例有故障,哨兵能夠發送報警信息和故障轉移結果發送到管理員
自動故障轉移:主節點不能正常工做時,能夠將失效主節點其中一個從節點升級爲新的主節點
配置中心:客戶端初始化時經過哨兵來得到Redis服務的主節點地址
其中,集羣監控和自動故障轉移功能,使得哨兵能夠及時發現主節點故障並完成轉移,消息通知和配置中心是和客戶端的交互中體現
咱們知道了它是幹啥的,下一步就是須要了解它是如何作到的,知其然,而後知其因此然~
典型的哨兵架構以下圖:
由兩部分組成,哨兵節點和數據節點:
哨兵節點:監哨兵系統由一個或者多個哨兵節點組成,哨兵節點是特殊的Redis節點,不存儲數據
數據節點:主節點master和從節點slave都是數據節點
關於哨兵的工做原理,主要是理解定時任務、主觀下線和客觀下線的幾個概念
1)定時任務:每一個哨兵節點維護了3個定時任務,分別是向主從發送info命
令獲取最新的主從結構、經過發佈訂閱獲取其它哨兵節點信息、經過向其它節點發送ping命令進行心跳檢測
2)主觀下線:在心跳檢測中,若是其它節點超過必定時間未回覆,哨兵節點會將其進行主觀下線,即一個哨兵節點主觀的判斷下線
3)客觀下線:哨兵節點對主節點進行主觀下線以後,會經過sentinel is-master-down-by-addr命令向其它哨兵節點詢問該主節點的狀態,若是判斷該主節點主觀下線的哨兵數量達到必定的數值,則對該主節點進行客觀下線
客觀下線是主節點纔有的概念!若是從節點和哨兵節點發生故障,被哨兵主觀下線以後,不會有後續的客觀下線和故障轉移操做
故障轉移流程
一、選舉哨兵領導者:當主節點被判斷主觀下線以後,各個哨兵節點會進行協商,選舉出一個哨兵領導者,由該領導者進行故障轉移操做,監視該主節點的全部哨兵均可能成爲領導者,選舉使用的算法是Raft算法,基本思想就是先到先得;在一輪選舉中,哨兵A向B發送成爲領導者的申請,若是B沒有贊成過其它哨兵,則會贊成A成爲領導者
通常來講,哨兵領導者選擇的很快,誰先完成客觀下線,通常誰就能成爲哨兵領導者
二、選擇新的主節點:領導者哨兵開始故障轉移操做,在從節點中選擇出新的主節點;原則是,先過濾掉不健康的從節點,選擇優先級最高的從節點(經過slave-priority設置),若優先級沒法區分,則選擇複製偏移量最大的從節點,若扔沒法區分,則選擇runid最小的從節點
runid是服務器啓動時自動生成,必定能找出最小的節點
三、更新主從狀態:經過slaveof no one命令,讓選出來的從節點成爲主節點;並經過slaveof命令讓其餘節點成爲其從節點
四、設置原主節點:將已經下線的主節點(即6379)設置爲新的主節點的從節點,當6379從新上線後,它會成爲新的主節點的從節點
Redis哨兵切換主備時的數據丟失問題
數據丟失主要分爲如下兩種狀況:
異步複製致使數據丟失
腦裂致使數據丟失
異步複製丟失是由於master到slave的複製是異步的,若是數據還未複製完成,master宕機了便會形成數據丟失;腦裂,master所在機器忽然脫離了正常網絡,跟別的節點沒法鏈接,可是實際上這個master沒有掛掉,還活着,哨兵會認爲這個主節點掛掉了,從新選出一個新的主節點,此時便存在兩個master節點了
此時雖然某個slave被切換成了master,可是可能客戶端還未進行切換,仍是鏈接原來的master,繼續向原來master節點發送數據,形成數據丟失
解決數據丟失
咱們通常經過兩個參數來解決:
min-slaves-to-write 1
min-slaves-max-lag 10
要求至少有1個slave,數據複製和同步的延遲不能超過10秒,若是說一旦全部slave,數據複製和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了。
1)減小異步複製的數據丟失
有了min-slaves-max-lag這個配置,就能夠確保說,一旦slave複製數據和ack延時太長,就認爲可能master宕機後損失的數據太多了,那麼就拒絕寫請求,這樣能夠把master宕機時因爲部分數據未同步到slave致使的數據丟失下降的可控範圍內
2)減小腦裂的數據丟失
若是一個master出現了腦裂,跟其餘slave丟了鏈接,那麼上面兩個配置能夠確保說,若是不能繼續給指定數量的slave發送數據,並且slave超過10秒沒有給本身ack消息,那麼就直接拒絕客戶端的寫請求,這樣腦裂後的舊master就不會接受client的新數據,也就避免了數據丟失,上面的配置就確保了,若是跟任何一個slave丟了鏈接,在10秒後發現沒有slave給本身ack,那麼就拒絕新的寫請求,所以在腦裂場景下,最多就丟失10秒的數據
一些其餘
哨兵至少須要三個實例,來保證本身的健壯性
哨兵+主從結構不會保證數據零丟失,只能保證高可用性
哨兵節點本質是Redis節點,每一個哨兵節點只須要配置監控主節點,即可以自動發現其餘哨兵節點和從節點
在哨兵節點啓動和故障轉移過程當中,哨兵的配置文件會被重寫
接下來演示一個簡單的哨兵系統的部署來幫助你們理解,包含一個主節點,兩個從節點和三個哨兵節點,均部署在本機localhost上,經過端口號區別
部署主從節點
哨兵系統的主從節點和普通的主從節點沒啥區別,不須要額外的配置,咱們設置主節點端口號是6379,從節點端口號是6380和6381
#redis-6379.confport 6379daemonize yeslogfile "6379.log"dbfilename "dump-6379.rdb"
#redis-6380.confport 6380daemonize nologfile "6380.log"dbfilename "dump-6380.rdb"slaveof localhost 6379
#redis-6381.confport 6381daemonize nologfile "6381.log"dbfilename "dump-6381.rdb"slaveof localhost 6379
配置完上面的三個配置文件以後,咱們經過命令啓動主從節點
redis-server redis-6379.confredis-server redis-6380.confredis-server redis-6381.conf
節點啓動後,咱們鏈接主節點,經過info Replication命令查看,能夠看到connected_slaves:2,該主節點有兩個從節點
部署哨兵節點
哨兵節點本質上就是不含數據的Redis節點,3個哨兵節點的配置幾乎是同樣的,咱們只須要修改端口號相關便可(1637九、16380、16381)
#redis-16379.confport 16379daemonize yeslogfile "16379.log"sentinel monitor mymaster localhost 6379 2
其中sentinel monitor mymaster localhost 6379 2配置的含義是,該哨兵節點監控localhost這個主節點,該主節點名字是mymaster,參數2則是和主節點的故障斷定有關,至少須要2個哨兵節點贊成,才能斷定主節點故障並進行故障轉移
哨兵節點的啓動方式:
redis-sentinel redis-16379.confredis-server redis-16379.conf --sentinel
咱們鏈接上端口號16379的客戶端,經過info sentinel命令查看從節點和相應的哨兵節點信息(鏈接命令redis-server.exe -p 16379