redis的主從復制有個缺點:
master宕機,需要手動把一個slave改為master,這期間master不存在,不能對外提供服務,且不一定能即使發現master宕機了。
主從復制表面上是高可用的,實際上並不是。
哨兵機制:
也叫做哨兵模式,監控master、slave的狀態,若master故障,自動從slave中選出一個新的master,並將變化通知到管理員、redis客戶端。實現了redis主從復制的高可用。
sentinel 哨兵
實現哨兵模式
實現哨兵要用到2個文件:
- redis的bin下面有一個可執行文件redis-sentinel
- redis的解壓目錄下有一個配置文件sentinel.conf,復制到/usr/local/redis/conf下,當然放哪兒都行
若多台虛擬機上模擬,無需修改端口號、各種文件保存位置,但太吃內初。
若在一台虛擬機上模擬,將redis復制多份,放到/usr/local/redis下,依次重命名為redis1、redis2....,並修改端口號、文件保存路徑。
修改sentinel.conf中的幾個參數:
bind 192.168.1.7 172.0.0.1 #綁定本機ip。可同時綁定多個,優先使用前面的,把實際ip寫在前面。
#protected-mode no #關閉保護模式(不使用保護模式) port 26379 #修改要使用的端口號
daemonize yes #作為守護線程,后台啟動 sentinel monitor mymaster 192.168.1.7 6379 2 #指定要監控的master的ip、port,客觀下線指標(閾值)
#sentinel auth-pass mymaster abcd #如果master設置了密碼,需要寫上master的密碼
先啟動master、slave,等master、slave都啟動了,再啟動各個sentinel。
我們在sentinel.conf中配置的是master的ip、port,sentinel是通過master找到該master的slave,所以要先啟動master、slave。
啟動哨兵:
./redis-sentinel ../conf/sentinel.conf
就是執行redis的bin下面的redis-sentinel,指定配置文件sentinel.conf的位置。
ps -ef | grep sentinel 看到哨兵已經啟動:(也可以grep redis)
連接到某個哨兵節點:
./redis-cli -h 192.168.1.8 -p 26379 #哨兵的ip、port
redis-cli不僅可以連接到redis-server,還可以連接到redis-sentinel,換成對應的端口即可。
關閉方式和redis-server一樣,通過redis-cli發送一個shutdown命令。
看下該哨兵節點的監控信息:
info sentinel
監控的master數量、監控的各master節點的信息都可以看到,包括master的名稱、ip、port、slave數量。
sentinels是指該master是否被哨兵監控,1表示正在被哨兵監控,並不是監控此master的哨兵數量。
status為ok,表示該master狀態正常。
關閉master,重新執行上面的命令,看到status=sdown,s即subjectively,主觀。
每個sentinel每秒都會ping一下監控的所有的master、slave節點,如果在30s內沒有收到master的回復,此sentinel節點主觀上就認為master down掉了。將其標識為sdown。
如果標識master down掉的sentinel節點達到指定值(閾值),就客觀上認為master確實down掉了,所有監控該master的sentinel節點都將master標識為odown。
過一段時間再此執行上面的命令,發現status=odown,o即objectively ,客觀。
連接到某個slave,info replication看下主從信息:
看到master已經從1.7換成了1.8。
看下某個sentinel的sentinel.log:
先是本sentinel將master標識為sdown,主觀下線
然后標識為odown,客觀下線。quorum即設置的閾值,有多個sentinel節點將其標識為下線就認為master確實down掉了。不小心把閾值改成了1......
try-failover 嘗試進行故障轉移,認為1.7發生故障不能再工作,需要把master這個位子轉交給某個slave。failover 故障轉移,fail over。
elected-leader 開始在slave中選新的master
selected-slave 選中了1.8作為新的master
failover-state 是故障轉移的狀態、進程,包括:
send-slaveof-noone 向1.8發送slaveof no one,即擺脫slave的地位
wait-promotion 等待1.8晉升為master,promotion 促進、提升、晉升
promoted 晉升完成,1.8成為新的master
之后就是其它slave從新的master處同步數據。
日志是很重要的,發生了錯誤,看下日志基本都能發現問題所在。
比如你把master down掉了,但一直沒有選舉新的master,日志中顯示master、各個slave都是sdown,一直沒有標識odown,
slave明明是正常的,卻顯示sdown,多半是鏈路不通,看一下能不能ping通,能ping通就再看下端口有沒有弄好。
master down掉了,sentinel從哪里獲取slave的ip、port?
sentinel剛連接master的時候,就會通過master獲取到slave的節點信息,保存在sentinel本身的節點上,
並每秒ping一次各個slave,確定各個slave的狀態,sentinel本身來維護各slave的節點信息。
master down掉,sentinel節點上是有slave節點信息的,不影響。
晉升機制
redis.conf中可以配置slave的優先級:
10,25,100,數值越大優先級越高,自動選擇優先級大的。
如果優先級相同,看偏移量,偏移量小的說明數據新,自動選擇偏移量小的。
說明
- 選舉期間的寫指令仍會全部丟失,但比手動配置新的master效率要高很多
- 如果原來的master重新上線,會作為新master的slave
- slave晉升為master后會獲得寫權限,可以執行寫指令
sentinel.conf 參數詳解
默認開啟值保護模式,只能本地訪問,即只能以127.0.0.1來訪問redis-sentinel。
默認都是注釋掉的,如果只在一個虛擬機中模擬,不用配置,
但實際運維時需要用bind綁定實際ip,綁定之后,才能連上指定的redis-sentinel
./redis-cli -h 192.168.1.8 -p 26379
否則只能連接到本地的redis-sentinel,因為默認就是127.0.0.1
可以綁定多個ip,優先使用前面的ip。
使用bind,會自動關閉保護模式,讓protected-mode注釋掉即可,不用管。
如果前面使用bind,后面開啟保護模式(yes),后面的配置會覆蓋前面的配置,同時使用時要注意這個問題。
端口有個很大的坑,很多人都是在一台虛擬機上模擬的,修改下端口就行了,不需要開啟防火牆,都是127.0.0.1,就在本地,開不開啟端口,sentinel之間都可以通信。
但實際運維時,要在防火牆中開啟26379端口,各個sentinel節點要用此端口通信,統計將master標識為sdown的節點數、選舉新master等等都需要sentinel節點之間交互。
日志文件我習慣就放在redis下,好找。
指定要監測的master的ip、port,master-name只能包含字母、數字、點、短橫、下划線。
quorum指定odown閾值,標識master為sdown的sentinel節點數達閾值,就認為master odown,重新選舉master。
quorum 一般指定為sentinel節點數的一半+1,比如5=>3,10=>6。
選舉出新的master后,會以發布/訂閱的方式通知其他的slave,自動修改配置文件,讓它們附屬於新的master。
如果master設置了密碼,需要寫上密碼。
redis服務器不用設置密碼,如果要設置密碼,master、slave設置的密碼應該一致,不然更換master時,在sentinel中指定的master密碼可能與晉升為master的slave的設置的密碼不一致。
指定sentinel多少秒內沒收到master的回復就認為master down掉了,將其標識為sdown。默認30s。
指定並行復制的slave節點數。選舉出新的master后,其它slave要從新master處同步數據,所有slave一起復制數據,新master的IO開銷很大,所以設置一個限制。
指定故障遷移的超時時間,在指定時間內未完成故障遷移,就認為故障遷移失敗。默認3min。
master-name代表這一組主從復制節點中的master,不是代表某個固定的節點。
發生WARNING級別的問題,比如sdown、odown,會自動調用此參數指定的腳本,傳入事件類型、事件描述。
我們可以自己寫腳本,通過email等方式將信息通知給管理員,使用此參數指定腳本路徑即可。
當選舉出新的master時,會自動執行此參數執行的腳本,傳入上一任master的ip、port和新master的ip、port。
我們可以自己寫腳本,把這個變化通知給redis客戶端,讓客戶端改下master的配置,以后把請求發給新的master。
sentinel往往是集群的,以達到高可用,某個sentinel節點掛掉也不影響。
一個sentinel集群用來監控單個主從復制,redis集群(即多個主從復制)需要用多個sentinel集群來監控。
哨兵只是配置提供者,向redis客戶端、主從復制節點提供master節點的配置信息(ip、port),並非代理。
redis-cli的常見用法:
./redis-cli -h 192.168.1.7 #端口默認值是6379
auth abcd #驗證密碼,密碼會加密傳輸 ./redis-cli -h 192.168.1.7 -a abcd #-a或-u指定redis-server的密碼,這種是使用http明文傳輸,不安全,會提示不安全,但仍可以用
./redis-cli -h 192.168.1.7 shutdown #關閉127.168.1.7上的redis-server,如果redis-server沒密碼,可以這么做,但有密碼就需要先連上,auth驗證密碼,再shutdown關閉
./redis-cli -h 192.168.1.7 -p 26379 #連接到redis-sentinel,端口很好記,就是redis的端口6379前面加個2
./redis-cli -h 192.168.1.7 -p 26379 shutdown #關閉192.168.1.7上的redis-sentinel