???每日一句
最美好的生活方式是和一群志同道合的人,一起奔跑在理想的路上,回頭有一路的故事,低頭有堅定的腳步,抬頭有清晰的遠(yuǎn)方!
??? Sentinel存在的意義
??? Sentinel出現(xiàn)的前提背景
在前面Redis技術(shù)系列的章節(jié)中,我們介紹了相關(guān)Redis持久化機(jī)制和Redis主從架構(gòu)的探究。兩者的相輔相成實(shí)現(xiàn)了Redis的數(shù)據(jù)高可用性以及服務(wù)的可擴(kuò)展性和負(fù)載性,但是只依靠持久化方案和主從復(fù)制能力(負(fù)載和數(shù)據(jù)的榮譽(yù)),在出現(xiàn)服務(wù)宕機(jī)的時候,故障切換無法自動去實(shí)現(xiàn),還需要手工,這對人工成本造成了巨大的損失以及不穩(wěn)定性。
??? 持久化+主從復(fù)制后的仍存在的痛點(diǎn)
當(dāng) 主服務(wù)器下線后無法恢復(fù)服務(wù)使用主從復(fù)制,在master節(jié)點(diǎn)下線后,只能夠手動將 slave 節(jié)點(diǎn)切換為 master,但是不能自動完成故障轉(zhuǎn)移。
??? Sentinel的加入才夠完整
Sentinel(哨兵)是Redis的高可用性解決方案:由一個或多個Sentinel實(shí)例組成的Sentinel系統(tǒng)可以監(jiān)視任意多個主服務(wù)器,以及這些主服務(wù)器屬下的所有從服務(wù)器,并在被監(jiān)視的主服務(wù)器進(jìn)入下線狀態(tài)時,自動將下線主服務(wù)器屬下的某個從服務(wù)器升級為新的主服務(wù)器。
主從持久化機(jī)制與加入哨兵之后的對比:
???Sentinel的主要功能
Redis Sentinel為Redis提供了完整的高可用解決方案。實(shí)際上這意味著使用Sentinel可以部署一套Redis,在沒有人為干預(yù)的情況下去應(yīng)付各種各樣的失敗事件。同時提供了一些其他的功能,例如:監(jiān)控、通知、并為client提供配置。
???Sentinel的概念定義
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案 ,當(dāng)用Redis做Master-slave的高可用方案時,假如master宕機(jī)了,Redis本身(包括它的很多客戶端)都沒有實(shí)現(xiàn)自動進(jìn)行主備切換,而Redis-sentinel本身也是一個獨(dú)立運(yùn)行的進(jìn)程,它能監(jiān)控多個master-slave集群,發(fā)現(xiàn)master宕機(jī)后能進(jìn)行自動切換。
Redis從 2.8發(fā)布了一個穩(wěn)定版本的Redis Sentinel 。當(dāng)前版本的 Sentinel稱為Sentinel 2。它是使用更強(qiáng)大和更簡單的預(yù)測算法來重寫初始Sentinel實(shí)現(xiàn)。(Redis2.6版本提供Sentinel 1版本,但是有 一些問題)。
???Sentinel的功能分布
-
監(jiān)控(Monitoring):Sentinel會不斷的檢查你的主節(jié)點(diǎn)和從節(jié)點(diǎn)是否正常工作。
-
通知(Notification):被監(jiān)控的Redis實(shí)例如果出現(xiàn)問題,Sentinel可以通過API(pub)通知系統(tǒng)管理員或者其他程序。
-
自動故障轉(zhuǎn)移(Automatic failover):如果一個主節(jié)點(diǎn)沒有按照預(yù)期工作,Sentinel 會開始進(jìn)行故障轉(zhuǎn)移,把一個從節(jié)點(diǎn)提升為主節(jié)點(diǎn),并重新配置其他的從節(jié)點(diǎn)使用新的主節(jié)點(diǎn),其他的從節(jié)點(diǎn)會開始復(fù)制新的主節(jié)點(diǎn),并且使用Redis服務(wù)的應(yīng)用程序在連接的時候也被通知新的地址。
-
配置提供(Configuration provider):客戶端可以把 Sentinel 作為權(quán)威的配置發(fā)布者來獲得最新的maste 地址。如果發(fā)生了故障轉(zhuǎn)移,Sentinel集群會通知客戶端新的master地址,并刷新 Redis 的配置。(sentinel會返回最新的master地址)
???Sentinel的分布特性
-
如果只使用單個sentinel進(jìn)程來監(jiān)控redis集群是不可靠的,當(dāng)sentinel進(jìn)程宕掉后(sentinel本身也有單點(diǎn)問題,single-point-of-failure)整個集群系統(tǒng)將無法按照預(yù)期的方式運(yùn)行。所以有必要將sentinel集群。
-
Redis Sentinel是一個分布式系統(tǒng),Sentinel運(yùn)行在有許多Sentinel進(jìn)程互相合作的環(huán)境下,它本身就是這樣被設(shè)計的。有許多Sentinel進(jìn)程互相合作的優(yōu)點(diǎn)如下:
-
當(dāng)多個Sentinel同意一個master不再可用的時候,就執(zhí)行故障檢測。這明顯降低了錯誤概率。
-
即使并非全部的Sentinel都在工作,Sentinel也可以正常工作,這種特性,讓系統(tǒng)非常的健康(最好是奇數(shù)個,因?yàn)椴蝗菀走x舉成為同票)。
-
分布方式總體深入下圖所示:
???Sentinel的基本原理
總體而言:多個 Sentinel 進(jìn)程(progress), 這些進(jìn)程使用流言協(xié)議(gossip protocols)來 接收關(guān)于主服務(wù)器是否下線的信息, 并使用投票協(xié)議(agreement protocols)來決定是否執(zhí)行自動故障遷移, 以及選擇哪個從服務(wù)器作為新的主服務(wù)器。
???Sentinel的主觀下線(SDOWN)
一個服務(wù)器必須在 master-down-after-milliseconds 毫秒內(nèi), 一直返回?zé)o效回復(fù)才會被 Sentinel 標(biāo)記為主觀下線。
-
在Sentinel哨兵的運(yùn)行階段,(其會向其他的Sentinel哨兵、master和slave發(fā)送消息確認(rèn)其是否存活),如果在指定的時間內(nèi)未收到正?;貞?yīng),暫時認(rèn)為對方掛起了(被標(biāo)記為主觀宕機(jī)–SDOWN)。
- 【注意:當(dāng)只有單個sentinel實(shí)例對redis實(shí)例做出無響應(yīng)的判斷,此時進(jìn)入主觀判斷,不會觸發(fā)自動故障轉(zhuǎn)移等操作。】
- 【注意:一個服務(wù)器必須在 master-down-after-milliseconds 毫秒內(nèi), 一直返回?zé)o效回復(fù)才會被 Sentinel 標(biāo)記為主觀下線】
???Sentinel的客觀下線(ODOWN)
-
當(dāng)多個Sentinel哨兵(數(shù)量由quorum參數(shù)設(shè)定)都報告同一個master沒有響應(yīng)了,通過投票算法(Raft算法),系統(tǒng)判斷其已死亡(被標(biāo)記為客觀宕機(jī)–ODOWN)。
- 多個 Sentinel 實(shí)例在對同一個服務(wù)器做出 SDOWN 判斷, 并且通過 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服務(wù)器下線判斷。
- Sentinel可以通過向另一個 Sentinel 發(fā)送 SENTINEL is-master-down-by-addr 命令來詢問對方是否認(rèn)為給定的服務(wù)器已下線。
???Sentinel下線操作
-
從主觀下線狀態(tài)切換到客觀下線狀態(tài)并沒有使用嚴(yán)格的法定人數(shù)算法(strong quorum algorithm), 而是使用了流言協(xié)議: 如果 Sentinel 在給定的時間范圍內(nèi)(master_down_after_milliseconds), 從其他 Sentinel 那里接收到了足夠數(shù)量的主服務(wù)器下線報告, 那么 Sentinel 就會將主服務(wù)器的狀態(tài)從主觀下線改變?yōu)榭陀^下線。 如果之后其他 Sentinel 不再報告主服務(wù)器已下線, 那么客觀下線狀態(tài)就會被移除。
-
客觀下線條件只適用于主服務(wù)器: 對于任何其他類型的 Redis 實(shí)例(其他sentinel和slave服務(wù)節(jié)點(diǎn)), Sentinel 在將它們判斷為下線前不需要進(jìn)行協(xié)商, 所以從服務(wù)器Slave或者其他 Sentinel 永遠(yuǎn)不會達(dá)到客觀下線條件。
???Sentinel的主從切換
- 此時Sentinel集群會選取領(lǐng)頭的哨兵(leader)進(jìn)行故障恢復(fù),從現(xiàn)有slave節(jié)點(diǎn)中選出(算法后續(xù)有介紹)一個提升為Master,并把剩余Slave都指向新的Master,繼續(xù)維護(hù)主從關(guān)系。
???Sentinel自動發(fā)現(xiàn)機(jī)制
-
那么,Sentinel集群的機(jī)器是如何發(fā)現(xiàn)集群中的其他機(jī)器呢?
- 使用廣播?很顯然不合適,既然是redis的產(chǎn)品,自然要充分運(yùn)用redis功能,Sentinel集群節(jié)點(diǎn)利用了Redis master的發(fā)布/訂閱機(jī)制去自動發(fā)現(xiàn)其它節(jié)點(diǎn)。
每個Sentinel使用發(fā)布/訂閱的方式持續(xù)地傳播master的配置版本信息,配置傳播的發(fā)布/訂閱管道是: sentinel:hello,我們可以通過訂閱其頻道查看頻道中的消息,如下:
??? Sentinel 利用 pub/sub(發(fā)布/訂閱):
訂閱了每個 master 和 slave 數(shù)據(jù)節(jié)點(diǎn)的 sentinel:hello 頻道,去自動發(fā)現(xiàn)其它也監(jiān)控了統(tǒng)一 master 的 sentinel 節(jié)點(diǎn),Sentinel 向每 1s 向 sentinel:hello 中發(fā)送一條消息,包含了其當(dāng)前維護(hù)的最新的master 配置。
-
如果某個sentinel發(fā)現(xiàn)自己的配置版本低于接收到的配置版本,則會用新的配置更新自己的 master 配置與發(fā)現(xiàn)的 Sentinel 之間相互建立命令連接,之后會通過這個命令連接來交換對于 master 數(shù)據(jù)節(jié)點(diǎn)的看法。
-
sentinel的狀態(tài)會被持久化地寫入sentinel的配置文件中。每次當(dāng)收到一個新的配置時,或者新創(chuàng)建一個配置時,配置會被持久化到硬盤中,并帶上配置的版本戳。這意味著,可以安全的停止和重啟sentinel進(jìn)程。
???Sentinel的發(fā)現(xiàn)方式
原理中提及到了,當(dāng)sentinel發(fā)現(xiàn)主庫客觀下線時候會進(jìn)行領(lǐng)頭哨兵選舉(超過半數(shù)切大于閾值)進(jìn)行故障恢復(fù),其選舉算法采用Raft算法,這也為什么說其設(shè)計思想類似與zookpeer,選舉過程大體如下:
-
發(fā)現(xiàn)主庫客觀下線的哨兵節(jié)點(diǎn)(這里稱為A)向每個哨兵節(jié)點(diǎn)發(fā)送命令要求對方選舉自己為領(lǐng)頭哨兵(leader);
-
如果目標(biāo)哨兵沒有選舉過其他人,則同意將A選舉為領(lǐng)頭哨兵;
-
如果A發(fā)現(xiàn)有超過半數(shù)且超過quorum參數(shù)值的哨兵節(jié)點(diǎn)同意選自己成為領(lǐng)頭哨兵,則A哨兵成功選舉為領(lǐng)頭哨兵。
- 【sentinel集群執(zhí)行故障轉(zhuǎn)移時需要選舉leader,此時涉及到majority,majority 代表 sentinel 集群中大部分 sentinel 節(jié)點(diǎn)的個數(shù),只有大于等于 max(quorum, majority) 個節(jié)點(diǎn)給某個 sentinel 節(jié)點(diǎn)投票,才能確定該sentinel節(jié)點(diǎn)為leader,majority 的計算方式為:num(sentinels) / 2 + 1】
-
當(dāng)有多個哨兵節(jié)點(diǎn)同時參與領(lǐng)頭哨兵選舉時,出現(xiàn)沒有任何節(jié)點(diǎn)當(dāng)選可能,此時每個參選節(jié)點(diǎn)等待一個隨機(jī)時間進(jìn)行下一輪選舉,直到選出領(lǐng)頭哨兵。
???故障恢復(fù)時從Slave中間選出Master的算法
-
按照slave優(yōu)先級進(jìn)行排序,slave-priority越低,優(yōu)先級就越高;
-
如果slave priority相同,那么比較復(fù)制偏移量,offset越靠后(越大)則表明和舊的主庫數(shù)據(jù)同步越接近,優(yōu)先級就越高 ;
-
如果上面兩個條件都相同,那么選擇一個run id最小的從庫;
主要根據(jù)slave-priority進(jìn)行排序做控制選舉,先比較slave_offset值越大優(yōu)先級越高,如果相等在獲取runid最小的(代表啟動時間越早)。
???Sentinel(哨兵)的運(yùn)作流程
-
每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 實(shí)例發(fā)送一個 PING 命令。(心跳機(jī)制)
-
如果一個實(shí)例(instance)距離最后一次有效回復(fù) PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實(shí)例會被 Sentinel 標(biāo)記為主觀下線。
-
如果一個Master被標(biāo)記為主觀下線,則正在監(jiān)視這個Master的所有 Sentinel 要以每秒一次的頻率確認(rèn)Master的確進(jìn)入了主觀下線狀態(tài)。(確認(rèn)投票下線)
-
當(dāng)有足夠數(shù)量的 Sentinel(大于等于配置文件指定的值)在指定的時間范圍內(nèi)確認(rèn)Master的確進(jìn)入了主觀下線狀態(tài), 則Master會被標(biāo)記為客觀下線 。
-
在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave發(fā)送 INFO 命令。(同步數(shù)據(jù))
-
當(dāng)Master被 Sentinel 標(biāo)記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
-
若沒有足夠數(shù)量的 Sentinel 同意 Master 已經(jīng)下線, Master 的客觀下線狀態(tài)就會被移除。
-
若 Master 重新向 Sentinel 的 PING 命令返回有效回復(fù), Master 的主觀下線狀態(tài)就會被移除。
???Sentinel部署配置
-
redis源碼中提供了 sentinel 配置的模板:sentinel.conf
-
Sentinel部署很簡單,只需要配置一下/etc/redis-sentinel.conf配置文件就可以了,如下
#工作端口
port 26379
#工作目錄
dir "/var/lib/redis/sentinel"
#sentinel id ,建議注釋掉,會自動生成
#sentinel myid 827f0104ad153f34db5a29b8cbb51ef21a31d6d5
#配置要監(jiān)控的master名字和地址,最后一個2代表當(dāng)sentinel集群中有2個sentinel認(rèn)為master故障時候才判定master真正不可用。
官方把該參數(shù)稱為quorum,在后續(xù)選舉領(lǐng)頭哨兵時候會用到
sentinel monitor mymaster 10.130.2.155 6379 2
#配置master密碼:配置主服務(wù)器的密碼(如沒設(shè)置密碼,可以省略)
sentinel auth-pass mymaster Password
#日志
logfile "/var/log/redis/sentinel.log"
配置完成后,使用systemctl start redis-sentinel啟動即可。
Sentinel可以調(diào)整的相關(guān)參數(shù)
#主觀SDOWN時間,單位毫秒,默認(rèn)30秒。(心跳檢測)
sentinel down-after-milliseconds mymaster 30000
#在發(fā)生failover主備切換時候,最多允許多少個slave同時同步新的master。這個數(shù)字越小,完成failover所需的時間就越長,但是如果這個數(shù)字越大,就意味著越多的slave因?yàn)閞eplication而不可用。可以通過將這個值設(shè)為 1 來保證每次只有一個slave處于不能處理命令請求的狀態(tài)。
sentinel parallel-syncs mymaster 1
#failover-time超時時間,當(dāng)failover開始后,在此時間內(nèi)仍然沒有觸發(fā)任何failover操作,當(dāng)前sentinel將會認(rèn)為此次failover失敗,單位毫秒。默認(rèn)3分鐘。
sentinel failover-timeout mymaster 180000
???核心配置
sentinel monitor <master-name> <ip> <redis-port> <quorum>: 監(jiān)控的 redis 主節(jié)點(diǎn)
#配置主服務(wù)器的密碼(如沒設(shè)置密碼,可以省略)
sentinel auth-pass mymaster 123456
#修改心跳檢測 5000毫秒
sentinel down-after-milliseconds mymaster 5000
- sentinel 是 redis 配置的提供者,而不是代理,客戶端只是從 sentinel 獲取數(shù)據(jù)節(jié)點(diǎn)的配置,因此這里的 ip 必須是 redis 客戶端能夠訪問的。
???Sentinel 啟動
雖然哨兵(sentinel) 釋出為一個單獨(dú)的可執(zhí)行文件 redis-sentinel ,但實(shí)際上它只是一個運(yùn)行在特殊模式下的 Redis 服務(wù)器,你可以在啟動一個普通 Redis 服務(wù)器時通過給定 --sentinel 選項來啟動哨兵(sentinel)。
如果你使用redis-sentinel可執(zhí)行文件,你可以使用下面的命令來運(yùn)行Sentinel:
$ redis-sentinel /path/to/sentinel.conf
當(dāng)然也可以采用 redis服務(wù)的方式啟動:
$ redis-server sentinel.conf --sentinel &
兩種方式是一樣的。
不管咋樣,使用一個配置文件來運(yùn)行Sentinel是必須的,這個文件被系統(tǒng)使用來存儲當(dāng)前狀態(tài),如果重啟,這些狀態(tài)會被重新載入。如果沒有配置文件或者配置文件的路徑不對,Sentinel將會拒絕啟動。
默認(rèn)情況下,Sentinels監(jiān)聽TCP端口26379,所以為了讓Sentinels運(yùn)行,你的機(jī)器的26379端口必須是打開的,用來接收其他Sentinel實(shí)例的連接,否則,Sentinels不能互相交流,也不知道該干什么,也不會執(zhí)行故障轉(zhuǎn)移。
1. 初始化一個普通的redis服務(wù)器
2. 加載Sentinel專用配置,例如命令表、參數(shù)等,Sentinel 使用 sentinel.c 中的命令表、函數(shù)等配置,普通 Redis 則使用 redis.c 中的配置
3. 除了保存服務(wù)器一般狀態(tài)之外,Sentinel 還會保存 Sentinel 相關(guān)狀態(tài)
注意:
1 .當(dāng)啟動哨兵模式之后,如果你的master服務(wù)器宕機(jī)之后,哨兵自動會在從redis服務(wù)器里面 投票選舉一個master主服務(wù)器出來;這個主服務(wù)器也可以進(jìn)行讀寫操作!
-
如果之前宕機(jī)的主服務(wù)器已經(jīng)修好,可以正式運(yùn)行了。那么這個服務(wù)器只能進(jìn)行讀的操作,會自動跟隨由哨兵選舉出來的新服務(wù)器!
-
大家可以進(jìn)入./redis-cli,輸入info,查看你的狀態(tài)信息;
???Redis截止到現(xiàn)在仍存在的問題
-
[哨兵已解決] :一旦主節(jié)點(diǎn)宕機(jī),從節(jié)點(diǎn)晉升成主節(jié)點(diǎn),同時需要修改應(yīng)用方的主節(jié)點(diǎn)地址,還需要命令所有從節(jié)點(diǎn)去復(fù)制新的主節(jié)點(diǎn),整個過程需要人工干預(yù)。
-
[集群已解決] :節(jié)點(diǎn)的寫能力受到單機(jī)的限制。文章來源:http://www.zghlxwxcb.cn/news/detail-406619.html
-
[集群已解決] :節(jié)點(diǎn)的存儲能力受到單機(jī)的限制。文章來源地址http://www.zghlxwxcb.cn/news/detail-406619.html
到了這里,關(guān)于精華推薦 |【Redis技術(shù)探索】「底層架構(gòu)原理」幫你徹底搞定Sentinel的實(shí)現(xiàn)原理運(yùn)作機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!