QT的QList類的使用
一,哨兵概述
哨兵(sentinel),用於對主從結構中的每一臺伺服器進行監控,當主節點出現故障後通過投票機制來挑選新的主節點,並且將所有的從節點連線到新的主節點上。前面的主從是最基礎的提升Redis伺服器穩定性的一種實現方式,但我們可以看到master節點仍然是一臺,若主節點宕機,所有從伺服器都不會有新的資料進來,如何讓主節點也實現高可用,當主節點宕機的時候自動從從節點中選舉一臺節點提升為主節點就是哨兵實現的功能。
二,哨兵作用
1.監控:監控主從節點執行情況。
2.通知:當監控節點出現故障,哨兵之間進行通訊。
自動故障轉移:當監控到主節點宕機後,斷開與宕機主節點連線的所有從節點,然後在從節點中選取一個作為主節點,將其他的從節點連線到這個最新的主節點。最後通知客戶端最新的伺服器地址。
三,哨兵的工作方式
1.每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 例項傳送一個PING命令。
2.如果一個例項(instance)距離最後一次有效回覆PING命令的時間超過 own-after-milliseconds 選項所指定的值,則這個例項會被Sentinel標記為主觀下線。
3.如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態。
4.當有足夠數量的Sentinel(大於等於配置檔案指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態,則Master會被標記為客觀下線。
5.在一般情況下,每個Sentinel 會以每10秒一次的頻率向它已知的所有Master,Slave傳送 INFO 命令。
6.當Master被Sentinel標記為客觀下線時,Sentinel 向下線的 Master 的所有Slave傳送 INFO命令的頻率會從10秒一次改為每秒一次。
若沒有足夠數量的Sentinel同意Master已經下線,Master的客觀下線狀態就會被移除。 若 Master重新向7.Sentinel 的PING命令返回有效回覆,Master的主觀下線狀態就會被移除。
四,哨兵架構圖
五,哨兵部署
5.1哨兵環境
主機名 | ip地址埠 | 角色 |
---|---|---|
sentinel | 10.0.0.88 26380 | 哨兵1 |
sentinel | 10.0.0.88 26381 | 哨兵2 |
sentinel | 10.0.0.88 26382 | 哨兵3 |
5.2哨兵配置
# pid檔案路徑 pidfile /var/run/redis-sentinel.pid # 日誌檔案路徑 logfile "/var/log/sentinel.log" # 定義工作目錄 dir /tmp # 定義Redis主的別名, IP, 埠,這裡的2指的是需要至少2個Sentinel認為主Redis掛了才最終會採取下一步行為 # sentinel monitor [叢集名稱] [叢集主節點IP] [斷開] [] sentinel monitor mymaster 127.0.0.1 6379 2 # 如果mymaster 30秒內沒有響應,則認為其主觀失效 sentinel down-after-milliseconds mymaster 30000 # 如果master重新選出來後,其它slave節點能同時並行從新master同步資料的臺數有多少個,顯然該值越大,所有slave節點完成同步切換的整體速度越快,但如果此時正好有人在訪問這些slave,可能造成讀取失敗,影響面會更廣。最保守的設定為1,同一時間,只能有一臺幹這件事,這樣其它slave還能繼續服務,但是所有slave全部完成快取更新同步的程序將變慢。 sentinel parallel-syncs mymaster 1 # 該引數指定一個時間段,在該時間段內沒有實現故障轉移成功,則會再一次發起故障轉移的操作,單位毫秒 sentinel failover-timeout mymaster 180000 # 不允許使用SENTINEL SET設定notification-script和client-reconfig-script。 sentinel deny-scripts-reconfig yes # 主庫賬號密碼 sentinel auth-pass mymaster 123 sentinel auth-user mymaster default # 三個哨兵示例配置 [root@sentinel /usr/local/redis/conf]# egrep -v '^#|^$' sentinel_26380.conf port 26380 daemonize yes pidfile /var/run/redis-sentinel_26380.pid logfile "/usr/local/redis/conf/sentinel_26380.log" dir /tmp sentinel monitor mymaster 172.16.1.81 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes sentinel auth-pass mymaster 123 sentinel auth-user mymaster default
5.3 啟動多例項哨兵
[root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26380.conf
[root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26381.conf
[root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26382.conf
[root@sentinel /usr/local/redis/conf]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:26380 0.0.0.0:* LISTEN 11591/../bin/redis-
tcp 0 0 0.0.0.0:26381 0.0.0.0:* LISTEN 11600/../bin/redis-
tcp 0 0 0.0.0.0:26383 0.0.0.0:* LISTEN 11608/../bin/redis-
5.4 檢視哨兵監控狀態
[root@sentinel /usr/local/redis/conf]# ../bin/redis-cli -p 26380
127.0.0.1:26380> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "172.16.1.81"
5) "port"
6) "6379"
7) "runid"
8) "63e1b63288c82c1ff20784626042aeaadd23f2d0"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
5.5測試故障轉移
# 停掉主庫
[root@redis01 /usr/local/redis/conf]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 172.16.1.81:6379 0.0.0.0:* LISTEN 14345/../bin/redis-
[root@redis01 /usr/local/redis/conf]# kill -9 14345
# 檢視sentinel 82以變成主庫
127.0.0.1:26380> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "172.16.1.82"
5) "port"
6) "6379"
7) "runid"
8) "007268419484bb9391e38ccf617fbbfaabc36fa0"
9) "flags"
10) "master"
# 啟動主庫檢視
[root@redis01 /usr/local/redis/conf]# ../bin/redis-server redis.conf
# 已經變成從庫了
[root@redis01 /usr/local/redis/conf]# ../bin/redis-cli
127.0.0.1:6379> INFO replication
127.0.0.1:6379> AUTH 123
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:172.16.1.82
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:226331
# 檢視哨兵日誌
[root@sentinel /usr/local/redis/conf]# tail sentinel_26380.log
11591:X 18 Dec 2020 20:47:33.491 * +slave-reconf-sent slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379
11591:X 18 Dec 2020 20:47:34.460 * +slave-reconf-inprog slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379
11591:X 18 Dec 2020 20:47:34.460 * +slave-reconf-done slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379
# 81 檢測down掉
11591:X 18 Dec 2020 20:47:34.560 # -odown master mymaster 172.16.1.81 6379
11591:X 18 Dec 2020 20:47:34.560 # +failover-end master mymaster 172.16.1.81 6379
11591:X 18 Dec 2020 20:47:34.560 # +switch-master mymaster 172.16.1.81 6379 172.16.1.82 6379
# 82被重新選舉會主庫
11591:X 18 Dec 2020 20:47:34.560 * +slave slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.82 6379
11591:X 18 Dec 2020 20:47:34.560 * +slave slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379
11591:X 18 Dec 2020 20:48:04.594 # +sdown slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379
11591:X 18 Dec 2020 20:49:07.859 # -sdown slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379
六,sentinel管理命令
#連線sentinel管理埠
[root@sentinel ~]# 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) "172.16.1.51"
2) "6379
#重置所有名字和給定模式
127.0.0.1:26380> SENTINEL reset mymaster
#當主伺服器失效時,在不詢問其他Sentinel意見的情況下,強制開始一次自動故障遷移。
127.0.0.1:26380> SENTINEL failover mymaster
七,設定權重,指定主庫的優先順序
#檢視81的權重
127.0.0.1:6379> CONFIG GET slave-priority
1) "slave-priority"
2) "100"
#修改81的權重值為0
127.0.0.1:6379> CONFIG set slave-priority 0
OK
127.0.0.1:6379> CONFIG GET slave-priority
1) "slave-priority"
2) "0"
# 權重值越低越不會優先切換為主庫
八,哨兵故障轉移原理以及檢測機制
8.1 三個定時任務
1.每10秒每個sentinel會對master和slave執行info命令,這個任務達到兩個目的:
a)發現slave節點
b)確認主從關係
2.每2秒每個sentinel通過master節點的channel交換資訊(pub/sub)。master節點上有一個釋出訂閱的頻道(sentinel:hello)。sentinel節點通過__sentinel__:hello頻道進行資訊交換(對節點的"看法"和自身的資訊),達成共識。
3.每1秒每個sentinel對其他sentinel和redis節點執行ping操作(相互監控),這個其實是一個心跳檢測,是失敗判定的依據。
8.2 主觀下線與客觀下線
-
主觀下線
所謂主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個Sentinel例項對伺服器做出的下線判斷,即單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網路不通等等原因)。如果伺服器在down-after-milliseconds給定的毫秒數之內, 沒有返回 Sentinel 傳送的 PING 命令的回覆, 或者返回一個錯誤, 那麼 Sentinel 將這個伺服器標記為主觀下線(SDOWN )。sentinel會以每秒一次的頻率向所有與其建立了命令連線的例項(master,從服務,其他sentinel)發ping命令,通過判斷ping回覆是有效回覆,還是無效回覆來判斷例項時候線上(對該sentinel來說是“主觀線上”)。sentinel配置檔案中的down-after-milliseconds設定了判斷主觀下線的時間長度,如果例項在down-after-milliseconds毫秒內,返回的都是無效回覆,那麼sentinel回認為該例項已(主觀)下線,修改其flags狀態為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生產中要注意。 -
客觀下線
客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 例項在對同一個伺服器做出 SDOWN 判斷, 並且通過 SENTINEL is-master-down-by-addr 命令互相交流之後, 得出的伺服器下線判斷,然後開啟failover。
客觀下線就是說只有在足夠數量的 Sentinel 都將一個伺服器標記為主觀下線之後, 伺服器才會被標記為客觀下線(ODOWN)。
只有當master被認定為客觀下線時,才會發生故障遷移。
當sentinel監視的某個服務主觀下線後,sentinel會詢問其它監視該服務的sentinel,看它們是否也認為該服務主觀下線,接收到足夠數量(這個值可以配置)的sentinel判斷為主觀下線,既任務該服務客觀下線,並對其做故障轉移操作。
客觀下線條件只適用於主伺服器: 對於任何其他型別的 Redis 例項, Sentinel 在將它們判斷為下線前不需要進行協商, 所以從伺服器或者其他 Sentinel 永遠不會達到客觀下線條件。只要一個 Sentinel 發現某個主伺服器進入了客觀下線狀態, 這個 Sentinel 就可能會被其他 Sentinel 推選出, 並對失效的主伺服器執行自動故障遷移操。