前言
哨兵sentinel是redis自帶的高可用程序,可以發現並自動切換主從狀態的redis服務配置,而且哨兵sentinel還可以支持管理多套redis主從.
而應用可以通過類似jedis的驅動直接連接哨兵,來實現高可用.jedis會在哨兵sentinel裏發現真實的主庫地址,然後讓程序連上真實主庫地址操作.
不過這個架構有三個問題,第一,應用程序的配置要實現這個功能的話就要從連接真實IP的redis改成連接哨兵.第二,如果哨兵掛了,應用會報錯而無法切換(3.2還會出現).第三,如果一套哨兵管理多套redis主從,並不是很好管理.
解決的方法有兩個,一個是在哨兵前面加類似nginx的負載均衡來控制jedis訪問哨兵地址,另一個就是在redis主從上加入高可用vip的操作來代替jedis直連哨兵,因爲哨兵sentinel支持切換髮生時接入腳本操作.
這篇文章說的就是加入高可用vip方式.
哨兵sentinel通信原理
在講主題之前,我想想講一下哨兵sentinel的原理.
通訊原理:
當一個完全沒接入哨兵sentinel的redis主從裏,第一個哨兵sentinel主動和redis主庫通信,詢問有沒有其他的redis從庫和哨兵sentinel連接信息.如果沒有,這個哨兵sentinel就創建配置,等待同步其他哨兵信息.
然後,第二個哨兵連進redis主庫,詢問有沒有其他從庫和哨兵地址,這個時候,redis主庫告訴它有其他哨兵,這個時候,第二個哨兵就會主動和第一個哨兵同步哨兵信息,從而形成了兩個節點的哨兵sentinel集羣.
再然後,第三個,第四個哨兵也是如此同步信息,形成以個更大的集羣.
切換原理:
當一個哨兵發現主庫down了,會發送一個主觀掛起信息sdown給其他各個節點的哨兵,當其他哨兵的大多數(可以設定個數)都覺得主庫確實掛起down了,這時哨兵集羣內部會獲得了一個客觀掛起信息odown狀態,那麼第一個發起主觀掛起信息的哨兵sentinel纔會開始正式的redis主從切換工作.如果獲取不到足夠多的哨兵返回客觀掛起down信息,是不會觸發切換的,很好的避免了一些網絡原因導致的閃斷切換.
切換過程會把從庫提爲主庫,而主庫會變成從庫,如果故障主庫沒起來,雖然會切換不成功,但是從庫會繼續切換成主庫,而當故障主庫從新起來後,哨兵sentinel會主動連上去把他的狀態改成從庫,然後新從庫會自動重新同步主從數據和結構,不需要人爲干預.
最後,哨兵sentinel間會通信,從新同步最新的redis主從信息,等待下一次的切換,這個間隔時間也可以設置,一般是3秒.
搭建環境
怎麼搭建redis主從不是本文重點,所以就不展開說明了,只列舉相關重要參數.
打開redis配置文件redis.conf
#本機redis密碼 requirepass "123123" #當本機是從庫時,主機的密碼,通常爲了避免麻煩,會和上面一致,但是確實可以和上面不一致 masterauth "123123" #當本機是從庫時,主機的地址和端口 slaveof 172.25.111.187 6379
然後,後面來說哨兵sentinel的配置,打開配置文件sentinel.conf
#綁定可訪問的地址,0.0.0.0就是所有 bind 0.0.0.0 #網絡保護模式,no是外部網絡可以直接訪問,yes是需配置bind ip或者設置訪問密碼,哨兵不涉及數據,通常不需要配置密碼 protected-mode no #訪問端口 port 26379 #數據目錄,pid和日誌log dir "/data/redis/data" pidfile "/data/redis/data/config/sentinel_26379.pid" logfile "/data/redis/data/logs/sentinel_26379.log" #允許後臺運行 daemonize yes #需要監聽的redis主庫信息, #jdzxyd_189:項目名,隨便你改,只要你能懂就行 #172.25.111.187:主庫的IP地址,記住是主庫的 #6379:主庫的redis端口 #3:主觀掛起信息sdown確認個數,也就是說,如果3臺sentinel認爲主redis掛了,纔算真的掛,返回odown狀態. sentinel monitor jdzxyd_189 172.25.111.187 6379 3 #確認掛起的時間,也就是說如果5秒內jdzxyd_189項目的主庫沒有響應,就認爲SDOWN,單位是毫秒 sentinel down-after-milliseconds jdzxyd_189 5000 #failover過期時間.當failover開始後,在此時間內jdzxyd_189項目仍然沒有觸發任何failover操作,當前sentinel將會認爲此次failoer失敗.單位是毫秒 sentinel failover-timeout jdzxyd_189 15000 #這個jdzxyd_189項目的認證密碼 sentinel auth-pass jdzxyd_189 123123 #failover之後重配置客戶端,jdzxyd_189項目執行腳本時會傳遞大量參數,請參考相關文檔,這個腳本是用來配置VIP的 sentinel client-reconfig-script jdzxyd_189 /root/yw/change_vip_6379.sh
可能有人有疑問,究竟多少個哨兵纔算是合理的.鑑於我們monitor的參數可以設置,我們可以參考zookeeper的概念,就是大多數原則,如果總數是3臺哨兵,那麼monitor就設置2臺,如果總數是5,那麼monitor就設置3臺,如此類推.不過也要注意到的是,過多的哨兵,會影響切換時效速度,所以還是要綜合衡量.還有就是,別忘了一個哨兵是可以管理多個redis主從的,你可以考慮公共哨兵集羣+私有哨兵集羣組合方式,靈活多變.
然後,我們看看切換vip的腳本
#!/usr/bin/env bash #從哨兵client-reconfig-script傳過來的參數中,$6就是新主庫的IP,所以我們要獲取它 MASTER_IP=$6 #高可用HA的vip地址 VIP='172.25.111.189' #子網 NETMASK='24' #網卡名稱 INTERFACE='ens160' #虛擬網卡編號 key='1' ifctrl=/usr/sbin/ifconfig arpingd=/usr/sbin/arping sshh=/usr/bin/ssh timeoutd=/usr/bin/timeout #LOCAL_IP="`${ifctrl} ${INTERFACE}|grep 172.25|awk '{print $2}'|awk -F':' '{print $2}'`" LOCAL_IP="`${ifctrl} ${INTERFACE}|grep 172.25|awk '{print $2}'`" if [ ${MASTER_IP} = ${LOCAL_IP} ];then ping -c 1 ${VIP} > /dev/null 2>&1 if [ $? -eq 0 ];then ${timeoutd} 5 ${sshh} -o stricthostkeychecking=no ${VIP} "${ifctrl} ${INTERFACE}:${key} down" >/dev/null 2>&1 fi ${ifctrl} ${INTERFACE}:${key} ${VIP}/${NETMASK} ${arpingd} -q -c 1 -A ${VIP} -I ${INTERFACE} exit else ${ifctrl} ${INTERFACE}:${key} down exit fi
腳本功能就不打算細說了,自己研究下,不過我想強調的是,編寫腳本的時候,一定要注意環境,因爲linux不認windows的字符編碼,容易出現奇葩的事情.
一切就緒,就在主庫掛上vip,啓動redis和哨兵,那這個集羣就完事了
ifconfig ens160:1 172.25.111.189/24 /usr/local/bin/redis-server /data/redis/data/config/redis_6379.conf >/var/log/redis_6379.log 2>&1 /usr/local/bin/redis-sentinel /data/redis/data/config/sentinel_26379.conf >/var/log/sentinel_26379.log 2>&1
切換解析
我們可以從哨兵日誌/data/redis/data/logs/sentinel_26379.log看到切換的過程,可以看到有sdown,odown和腳本啓用的日誌都在裏面.
21081:X 19 Mar 18:22:55.600 # +sdown master pro_crs_yxt 10.233.39.33 6379
21081:X 19 Mar 18:22:55.617 # +new-epoch 4
21081:X 19 Mar 18:22:55.619 # +vote-for-leader 7480fbb4d41426431bdea0525f2b732c99af420b 4
21081:X 19 Mar 18:22:55.655 # +odown master pro_crs_yxt 10.233.39.33 6379 #quorum 4/3
21081:X 19 Mar 18:22:55.655 # Next failover delay: I will not start a failover before Thu Mar 19 18:23:26 2020
21081:X 19 Mar 18:23:02.589 # -sdown master pro_crs_yxt 10.233.39.33 6379
21081:X 19 Mar 18:23:02.589 # -odown master pro_crs_yxt 10.233.39.33 6379
從這段日誌可以看到,流程如下:
第一步,這個哨兵發現10.233.39.33 6379疑似掛起了,狀態是+sdown
第二步,這個哨兵向哨兵集羣發起了投票,在4個哨兵裏面有3個都覺得它確實掛了,所以狀態變成了+odown
第三步,開始failover
第四步,這個時候,10.233.39.33 6379起來了,狀態變爲-sdown
第五步,大家都覺得確實起來了,狀態變爲了-odown