Redis高可用sentinel
1.sentine介紹
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立運行的進程,它能監控多個master-slave集群,發現master宕機后能進行自動切換。
sentinel的構造
Sentinel 是一個監視器,它可以根據被監視實例的身份和狀態來判斷應該執行何種動作。
sentinel的功能
1)監控(Monitoring):
Sentinel會不斷地檢查你的主服務器和從服務器是否運作正常。
2)提醒(Notification):
當被監控的某個Redis服務器出現問題時,Sentinel可以通過API向管理員或者其他應用程序發送通知。
3)自動故障遷移(Automatic failover):
當一個主服務器不能正常工作時,Sentinel會開始一次自動故障遷移操作,它會將失效主服務器的其中一個從服務器升級為新的主服務器,并讓失效主服務器的其他從服務器改為復制新的主服務器;當客戶端試圖連接失效的主服務器時,集群也會向客戶端返回新主服務器的地址,使得集群可以使用新主服務器代替失效服務器。
發現并連接主服務器
Sentinel通過用戶給定的配置文件來發現主服務器。
Sentinel會與被監視的主服務器創建兩個網絡連接:
命令連接用于向主服務器發送命令。
訂閱連接用于訂閱指定的頻道,從而發現監視同一主服務器的其他Sentinel。
配置文件示例
redis-sentinel sentinel.conf
############ master1 configure ##############
sentinel monitor master1 127.0.0.1 6379 2
sentinel down-after-milliseconds master1 30000
sentinel parallel-syncs master1 1
sentinel failover-timeout master1 900000
############ master2 configure ##############
sentinel monitor master2 127.0.0.1 12345 5
sentinel down-after-milliseconds master2 50000
sentinel parallel-syncs master2 5
sentinel failover-timeout master2 450000
發現并連接從服務器
Sentinel通過向主服務器發送INFO命令來自動獲得所有從服務器的地址
跟主服務器一樣,Sentinel 會與每個被發現的從服務器創建命令連接和訂閱連接。
發現其他sentinel
Sentinel 會通過命令連接向被監視的主從服務器發送 “HELLO” 信息,該消息包含 Sentinel 的 IP、端口號、ID 等內容,以此來向其他 Sentinel 宣告自己的存在。與此同時Sentinel 會通過訂閱連接接收其他 Sentinel 的“HELLO” 信息,以此來發現監視同一個主服務器的其他 Sentinel 。
1)一個Sentinel可以與其他多個Sentinel進行連接,各個Sentinel之間可以互相檢查對方的可用性,并進行信息交換。你無須為運行的每個 Sentinel 分別設置其他 Sentinel 的地址,因為Sentinel可以通過發布與訂閱功能來自動發現正在監視相同主服務器的其他 Sentinel ,這一功能是通過向頻道__sentinel__:hello發送信息來實現的。
2)與此類似,你也不必手動列出主服務器屬下的所有從服務器,因為 Sentinel 可以通過詢問主服務器來獲得所有從服務器的信息。每個Sentinel會以每兩秒一次的頻率,通過發布與訂閱功能,向被它監視的所有主服務器和從服務器的__sentinel__:hello頻道發送一條信息,信息中包含了Sentinel的IP地址、端口號和運行ID(runid)。
3)每個Sentinel都訂閱了被它監視的所有主服務器和從服務器的__sentinel__:hello?頻道,查找之前未出現過的sentinel(looking for unknown sentinels)。當一個Sentinel發現一個新的Sentinel時,它會將新的Sentinel添加到一個列表中,這個列表保存了Sentinel已知的,監視同一個主服務器的所有其他 Sentinel 。Sentinel發送的信息中還包括完整的主服務器當前配置(configuration)。如果一個 Sentinel 包含的主服務器配置比另一個Sentinel發送的配置要舊,那么這個 Sentinel 會立即升級到新配置上。
4)在將一個新 Sentinel 添加到監視主服務器的列表上面之前,Sentinel 會先檢查列表中是否已經包含了和要添加的 Sentinel 擁有相同運行 ID 或者相同地址(包括 IP 地址和端口號)的 Sentinel ,如果是的話,Sentinel 會先移除列表中已有的那些擁有相同運行 ID或者相同地址的 Sentinel ,然后再添加新 Sentinel 。
多個sentinel之間連接
Sentinel之間只會互相創建命令連接,用于進行通信。因為已經有主從服務器作為發送和接收HELLO信息的中介,所以Sentinel之間不會創建訂閱連接。
檢測實例的狀態
Sentinel使用PING命令來檢測實例的狀態:如果實例在指定的時間內沒有返回回復,或者返回錯誤的回復,那么該實例會被 Sentinel 判斷為下線。
Redis的Sentinel中關于下線(down)有兩個不同的概念:
1)主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器做出的下線判斷。
2)客觀下線(Objectively Down,簡稱 ODOWN)指的是多個Sentinel實例在對同一個服務器做出SDOWN判斷,并且通過SENTINEL?is-master-down-by-addr命令互相交流之后,得出的服務器下線判斷。(一個 Sentinel可以通過向另一個Sentinel發送SENTINEL?is-master-down-by-addr命令來詢問對方是否認為給定的服務器已下線。)
如果一個服務器沒有在?master-down-after-milliseconds?選項所指定的時間內,對向它送PING命令的Sentinel返回一個有效回復(valid reply),那么Sentinel就會將這個服務器標記為主觀下線。
服務器對PING命令的有效回復可以是以下三種回復的其中一種:
1)返回?+PONG?。
2)返回?-LOADING?錯誤。
3)返回?-MASTERDOWN?錯誤。
如果服務器返回除以上三種回復之外的其他回復,又或者在指定時間內沒有回復Ping命令,那么Sentinel認為服務器返回的回復無效(non-valid)。
注意:一個服務器必須在master-down-after-milliseconds毫秒內,一直返回無效回復才會被Sentinel標記為主觀下線。
舉個例子,如果master-down-after-milliseconds選項的值為30000毫秒(30秒),那么只要服務器能在每29秒之內返回至少一次有效回復,這個服務器就仍然會被認為是處于正常狀態的。
從主觀下線狀態切換到客觀下線狀態并沒有使用嚴格的法定人數算法(strong quorum algorithm),而是使用了流言協議:如果 Sentinel 在給定的時間范圍內,從其他Sentinel那里接收到了足夠數量的主服務器下線報告,那么Sentinel就會將主服務器的狀態從主觀下線改變為客觀下線。如果之后其他Sentinel不再報告主服務器已下線,那么客觀下線狀態就會被移除。
客觀下線條件只適用于主服務器:對于任何其他類型的Redis實例,Sentinel在將它們判斷為下線前不需要進行協商,所以從服務器或者其他 Sentinel 永遠不會達到客觀下線條件。
只要一個Sentinel發現某個主服務器進入了客觀下線狀態,這個Sentinel就可能會被其他Sentinel推選出,并對失效的主服務器執行自動故障遷移操作。
故障轉移FAILOVER
一次故障轉移操作由以下步驟組成:
1)發現主服務器已經進入客觀下線狀態。
2)基于Raft leader election協議?,進行投票選舉
3)如果當選失敗,那么在設定的故障遷移超時時間的兩倍之后,重新嘗試當選。如果當選成功,那么執行以下步驟。
4)選出一個從服務器,并將它升級為主服務器。
5)向被選中的從服務器發送?SLAVEOF?NO?ONE?命令,讓它轉變為主服務器。
6)通過發布與訂閱功能,將更新后的配置傳播給所有其他Sentinel,其他Sentinel對它們自己的配置進行更新。
7)向已下線主服務器的從服務器發送SLAVEOF命令,讓它們去復制新的主服務器。
8)當所有從服務器都已經開始復制新的主服務器時, leader Sentinel 終止這次故障遷移操作
每當一個Redis實例被重新配置(reconfigured)—— 無論是被設置成主服務器、從服務器、又或者被設置成其他主服務器的從服務器 —— Sentinel 都會向被重新配置的實例發送一個CONFIG REWRITE命令,從而確保這些配置會持久化在硬盤里。
Sentinel使用以下規則來選擇新的主服務器:
1)在失效主服務器屬下的從服務器當中,那些被標記為主觀下線、已斷線、或者最后一次回復PING命令的時間大于五秒鐘的從服務器都會被淘汰。
2)在失效主服務器屬下的從服務器當中,那些與失效主服務器連接斷開的時長超過down-after選項指定的時長十倍的從服務器都會被淘汰。
3)在經歷了以上兩輪淘汰之后剩下來的從服務器中,我們選出復制偏移量(replication offset)最大的那個從服務器作為新的主服務器;如果復制偏移量不可用,或者從服務器的復制偏移量相同,那么帶有最小運行ID的那個從服務器成為新的主服務器。
Sentinel自動故障遷移的一致性特質:
1)Sentinel自動故障遷移使用Raft算法來選舉領頭(leader)Sentinel ,從而確保在一個給定的周期(epoch)里,只有一個領頭產生。
2)這表示在同一個周期中, 不會有兩個 Sentinel 同時被選中為領頭,并且各個 Sentinel 在同一個節點中只會對一個領頭進行投票。
3)更高的配置節點總是優于較低的節點,因此每個 Sentinel 都會主動使用更新的節點來代替自己的配置。
簡單來說,我們可以將Sentinel配置看作是一個帶有版本號的狀態。一個狀態會以最后寫入者勝出(last-write-wins)的方式(也即是,最新的配置總是勝出)傳播至所有其他Sentinel。
舉個例子:
1)當出現網絡分割(network partitions)時,一個Sentinel可能會包含了較舊的配置,而當這個Sentinel接到其他Sentinel發來的版本更新的配置時,Sentinel就會對自己的配置進行更新。
2)如果要在網絡分割出現的情況下仍然保持一致性, 那么應該使用 min-slaves-to-write 選項,讓主服務器在連接的從實例少于給定數量時停止執行寫操作,與此同時,應該在每個運行Redis主服務器或從服務器的機器上運行Redis Sentinel進程。
Sentinel狀態的持久化:
1)Sentinel 的狀態會被持久化在 Sentinel 配置文件里面。
2)每當Sentinel接收到一個新的配置,或者當領頭Sentinel為主服務器創建一個新的配置時,這個配置會與配置節點一起被保存到磁盤里面。
3)這意味著停止和重啟Sentinel進程都是安全的。
Sentinel在非故障遷移的情況下對實例進行重新配置:
1)即使沒有自動故障遷移操作在進行,Sentinel總會嘗試將當前的配置設置到被監視的實例上面。
特別是:
根據當前的配置,如果一個從服務器被宣告為主服務器,那么它會代替原有的主服務器,成為新的主服務器,并且成為原有主服務器的所有從服務器的復制對象。
2)那些連接了錯誤主服務器的從服務器會被重新配置, 使得這些從服務器會去復制正確的主服務器。
3)不過,在以上這些條件滿足之后,Sentinel在對實例進行重新配置之前仍然會等待一段足夠長的時間,確保可以接收到其他Sentinel發來的配置更新,從而避免自身因為保存了過期的配置而對實例進行了不必要的重新配置。
#######sentinel實戰及配置講解
環境準備
sentinel配置
?
#創建sentinel的配置文件目錄
[root@db01 ~]# mkdir /etc/redis/26380
#進入sentinel配置目錄
[root@db01 ~]# cd /etc/redis/26380/
#編輯配置文件
[root@db01 26380]# vim sentinel.conf
port 26380
dir "/etc/redis/26380"
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 5000
#啟動sentinel
[root@db01 26380]# redis-sentinel /etc/redis/26380/sentinel.conf &
?sentinel切換測試
?
#連接redis主庫
[root@db01 26380]# redis-cli -p 6379
#關閉主庫
127.0.0.1:6379> SHUTDOWN
#登錄原從庫6380
[root@db01 26380]# redis-cli -p 6380
#查看主從信息
127.0.0.1:6380> info replication
# Replication
role:master //由此可見,原從庫6380已經被提升為主庫
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=3552,lag=0 //從庫變成了6381
master_repl_offset:3566
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:3565
#開啟舊主庫6379
[root@db01 26380]# redis-server /etc/redis/6379/redis.conf
#連接舊主庫6379
[root@db01 26380]# redis-cli -p 6379
#查看主從信息
127.0.0.1:6379> info replication
# Replication
role:slave //角色變成了slave
master_host:127.0.0.1
master_port:6380 //主庫的端口是6380
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:37819
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
#在新主6380上查看主從信息
[root@db01 26380]# redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=45288,lag=1
slave1:ip=127.0.0.1,port=6379,state=online,offset=45421,lag=0 //6379自動加入了集群
master_repl_offset:45421
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:45420
sentinel monitor mymaster 127.0.0.1 6379 2
Sentinel 去監視一個名為mymaster的主服務器,這個主服務器的IP地址為127.0.0.1,端口號為6379,而將這個主服務器判斷為失效至少需要2個Sentinel同意(只要同意Sentinel的數量不達標,自動故障遷移就不會執行,不過要注意,無論你設置要多少個Sentinel同意才能判斷一個服務器失效,一個 Sentinel 都需要獲得系統中多數(majority) Sentinel 的支持,才能發起一次自動故障遷移,并預留一個給定的配置節點(configuration Epoch,一個配置節點就是一個新主服務器配置的版本號)。換句話說,在只有少數(minority)Sentinel進程正常運作的情況下,Sentinel 是不能執行自動故障遷移的。
sentinel down-after-milliseconds mymaster 5000
指定了Sentinel認為服務器已經斷線所需的毫秒數。如果服務器在給定的毫秒數之內,沒有返回Sentinel發送的Ping命令的回復,或者返回一個錯誤,那么Sentinel將這個服務器標記為主觀下線(subjectively down,簡稱SDOWN)。不過只有一個Sentinel將服務器標記為主觀下線并不一定會引起服務器的自動故障遷移:只有在足夠數量的Sentinel都將一個服務器標記為主觀下線之后,服務器才會被標記為客觀下線(objectively down, 簡稱?ODOWN?),這時自動故障遷移才會執行。
sentinel failover-timeout mymaster 180000?
自動故障切換的超時時間
sentinel parallel-syncs mymaster 1?
在執行故障轉移時,最多可以有多少個從服務器同時對新的主服務器進行同步,這個數字越小,完成故障轉移所需的時間就越長。如果從服務器被設置為允許使用過期數據集(參見對?redis.conf?文件中對?slave-serve-stale-data?選項的說明),那么你可能不希望所有從服務器都在同一時間向新的主服務器發送同步請求,因為盡管復制過程的絕大部分步驟都不會阻塞從服務器,但從服務器在載入主服務器發來的 RDB 文件時,仍然會造成從服務器在一段時間內不能處理命令請求:如果全部從服務器一起對新的主服務器進行同步,那么就可能會造成所有從服務器在短時間內全部不可用的情況出現。可以通過將這個值設為1來保證每次只有一個從服務器處于不能處理命令請求的狀態。
sentinel管理命令(不常用
#連接sentinel管理端口
[root@db01 26380]# redis-cli -p 26380
#檢測狀態,返回PONG
127.0.0.1:26380> PING
PONG
#列出所有被監視的主服務器
127.0.0.1:26380> SENTINEL masters
#列出所有被監視的從服務器
127.0.0.1:26380> SENTINEL slaves mymaster
#返回給定名字的主服務器的IP地址和端口號
127.0.0.1:26380> SENTINEL get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "6380"
#重置所有名字和給定模式
127.0.0.1:26380> SENTINEL reset mymaster
#當主服務器失效時,在不詢問其他Sentinel意見的情況下,強制開始一次自動故障遷移。
127.0.0.1:26380> SENTINEL failover mymaster
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/fangdecheng/p/10121374.html
總結
以上是生活随笔為你收集整理的Redis高可用sentinel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: to_date , to_char
- 下一篇: $.ajax的标准写法