Redis進階實踐之十 Redis哨兵集羣模式

1、引言

             上一篇文章咱們詳細的講解了Redis的主從集羣模式,其實這個集羣模式配置很簡單,只須要在Slave的節點上進行配置,Master主節點的配置不須要作任何更改,可是有一點,Master和Slave兩個節點的持久化配置儘可能保持一致,不然會有奇怪的問題出現。從今天開始咱們開始講Redis集羣模式的第二模式,也就是「哨兵」模式,該模式是從Redis的2.6版本開始提供的,可是當時這個版本的模式是不穩定的,直到Redis的2.8版本之後,這個哨兵模式才穩定下來,在生產環境中,若是想要使用Redis的哨兵模式,也會盡可能使用Redis的2.8版本以後的版本。不管是主從模式,仍是哨兵模式,這兩個模式都有一個問題,不能水平擴容,而且這兩個模式的高可用特性都會受到Master主節點內存的限制。還有一點,實現哨兵模式的配置也不簡單,甚至能夠說有些繁瑣,因此在工業場景裏這兩個模式都不建議使用,若是要使用必須有相關的問題的解決方案,以避免後續帶來的問題。

2、Redis Sentinel簡介

             Sentinel(哨兵)進程是用於監控redis集羣中Master主服務器工做的狀態,在Master主服務器發生故障的時候,能夠實現Master和Slave服務器的切換,保證系統的高可用,其已經被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本以後就穩定了下來。通常在生產環境也建議使用Redis的2.8版本的之後版本。哨兵(Sentinel) 是一個分佈式系統,你能夠在一個架構中運行多個哨兵(sentinel) 進程,這些進程使用流言協議(gossipprotocols)來接收關於Master主服務器是否下線的信息,並使用投票協議(Agreement Protocols)來決定是否執行自動故障遷移,以及選擇哪一個Slave做爲新的Master。每一個哨兵(Sentinel)進程會向其它哨兵(Sentinel)、Master、Slave定時發送消息,以確認對方是否」活」着,若是發現對方在指定配置時間(可配置的)內未獲得迴應,則暫時認爲對方已掉線,也就是所謂的」主觀認爲宕機」 ,英文名稱:Subjective Down,簡稱SDOWN。有主觀宕機,確定就有客觀宕機。當「哨兵羣」中的多數Sentinel進程在對Master主服務器作出 SDOWN 的判斷,而且經過 SENTINEL is-master-down-by-addr 命令互相交流以後,得出的Master Server下線判斷,這種方式就是「客觀宕機」,英文名稱是:Objectively Down, 簡稱 ODOWN。經過必定的vote算法,從剩下的slave從服務器節點中,選一臺提高爲Master服務器節點,而後自動修改相關配置,並開啓故障轉移(failover)。

            哨兵(sentinel) 雖然有一個單獨的可執行文件 redis-sentinel ,但實際上它只是一個運行在特殊模式下的 Redis 服務器,你能夠在啓動一個普通 Redis 服務器時經過給定 --sentinel 選項來啓動哨兵(sentinel),哨兵(sentinel) 的一些設計思路和zookeeper很是相似。

           Sentinel集羣之間會互相通訊,溝通交流redis節點的狀態,作出相應的判斷並進行處理,這裏的主觀下線狀態和客觀下線狀態是比較重要的狀態,它們決定了是否進行故障轉移,能夠 經過訂閱指定的頻道信息,當服務器出現故障得時候通知管理員,客戶端能夠將 Sentinel 看做是一個只提供了訂閱功能的 Redis 服務器,你不可使用 PUBLISH 命令向這個服務器發送信息,但你能夠用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令, 經過訂閱給定的頻道來獲取相應的事件提醒。一個頻道可以接收和這個頻道的名字相同的事件。 好比說, 名爲 +sdown 的頻道就能夠接收全部實例進入主觀下線(SDOWN)狀態的事件。

      一、Sentinel(哨兵)進程的做用:

              1】、監控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運做正常。

              2】、提醒(Notification):當被監控的某個Redis節點出現問題時, 哨兵(sentinel) 能夠經過 API 向管理員或者其餘應用程序發送通知。

              3】、自動故障遷移(Automatic failover):當一個Master不能正常工做時,哨兵(sentinel) 會開始一次自動故障遷移操做,它會將失效Master的其中一個Slave升級爲新的Master, 並讓失效Master的其餘Slave改成複製新的Master;當客戶端試圖鏈接失效的Master時,集羣也會向客戶端返回新Master的地址,使得集羣可使用如今的Master替換失效Master。Master和Slave服務器切換後,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的內容都會發生相應的改變,即,Master主服務器的redis.conf配置文件中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換。

      
       二、Sentinel(哨兵)進程的工做方式:

             1】、每一個Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集羣中的Master主服務器,Slave從服務器以及其餘Sentinel(哨兵)進程發送一個 PING 命令。

             2】、若是一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記爲主觀下線(SDOWN)。

             3】、若是一個Master主服務器被標記爲主觀下線(SDOWN),則正在監視這個Master主服務器的全部 Sentinel(哨兵)進程要以每秒一次的頻率確認Master主服務器的確進入了主觀下線狀態。

             4】、當有足夠數量的 Sentinel(哨兵)進程(大於等於配置文件指定的值)在指定的時間範圍內確認Master主服務器進入了主觀下線狀態(SDOWN), 則Master主服務器會被標記爲客觀下線(ODOWN)。

             5】、在通常狀況下, 每一個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集羣中的全部Master主服務器、Slave從服務器發送 INFO 命令。

             6】、當Master主服務器被 Sentinel(哨兵)進程標記爲客觀下線(ODOWN)時,Sentinel(哨兵)進程向下線的 Master主服務器的全部 Slave從服務器發送 INFO 命令的頻率會從 10 秒一次改成每秒一次。

             7】、若沒有足夠數量的 Sentinel(哨兵)進程贊成 Master主服務器下線, Master主服務器的客觀下線狀態就會被移除。若 Master主服務器從新向 Sentinel(哨兵)進程發送 PING 命令返回有效回覆,Master主服務器的主觀下線狀態就會被移除。


       三、哨兵模式的環境:

             1】、Master主服務器配置信息:IP:192.168.127.128, Port:6379,OS:Linux

             2】、Slave從服務器的配置信息:IP:192.168.127.129 Port:6379,OS:Linux

             3】、在Slave從服務器上安裝了一個哨兵進程(Sentinel),在Master服務器也安裝了一個哨兵進程(Sentinel)。

             因爲兩個Redis服務器都是安裝在Linux操做系統上,並且這兩個Redis服務器會在Master主服務器發生故障的時候會進行切換,必須保證兩個Redis服務器的端口號已經增長進了防火牆,或者把兩個Linux操做系統的防火牆關閉,不然會提示Master-link-Status:down,沒有鏈接上Master主服務器。解決辦法有兩個:第一個辦法是關閉兩個Linux操做系統的防火牆;第二個辦法是把各個Redis服務的端口號增長到防火牆裏面,容許經過該端口號進行通訊。能夠先使用命令 【firewall-cmd --query-port=6379/tcp】,若是結果是 No,那就繼續執行如下命令【firewall-cmd --add-port=6379/tcp】,命令執行後,返回Success,表示增長成功。這樣兩個Linux系統上的Redis服務器就能夠順利切換,執行哨兵模式的操做。


3、哨兵模式的配置

      下面是我使用的配置,須要修改的配置項我寫了出來,沒有更改的配置項就是用默認值,就不會寫出來:

      一、###### Master config(redis.conf)redis

         1.1、### NETWORK 設置:

                  bind 192.168.127.128  //綁定IP地址,能夠經過ifconfig 獲取Ip地址(在Linux系統下)

                  port 6379  //保持默認值,也能夠修改

                  timeout 30  //Client 端空閒斷開鏈接的時間


         1.2、### GENERAL 設置:

                  daemonize yes   //默認值是no,把值修改成yes,之後臺模式運行

                  logfile /root/application/program/redis-tool/logs/redis.log  //日誌文件的位置


         1.3、### SNAPSHOTTING 設置:

                  dir /root/application/program/redis-tool/datas   //SNAPSHOTTING文件的路徑


         1.4、### APPEND ONLY MODE 設置:

                  appendonly yes  //默認值是No,意思是不使用AOF增量持久化的方式,使用RDB全量持久化的方式。把No值改爲Yes,使用AOF增量持久化的方式

                  appendfsync always


      二、###### Slave Config(redis.conf)算法

          2.1、### NETWORK 設置:

                   bind 192.168.127.129   //綁定IP地址,能夠經過ifconfig 獲取Ip地址(在Linux系統下)

                   port 6379   //保持默認值,也能夠修改

                   timeout 30  //Client 端空閒斷開鏈接的時間


          2.2、### GENERAL 設置:

                   daemonize yes    //默認值是no,把值修改成yes,之後臺模式運行

                   logfile /root/application/program/redis/logs/redis.log  //日誌文件的位置


          2.3、### SNAPSHOTTING 設置:

                   dir /root/application/program/redis/datas  //SNAPSHOTTING文件的路徑


          2.4、### REPLICATION 設置:

                   slaveof 192.168.127.128 6379  //主服務器的Ip地址和Port端口號

                   slave-serve-stale-data no  //若是slave 沒法與master 同步,設置成slave不可讀,方便監控腳本發現問題。


          2.5、### APPEND ONLY MODE 設置:

                   appendonly yes  //默認值是No,意思是不使用AOF增量持久化的方式,使用RDB全量持久化的方式。把No值改爲Yes,使用AOF增量持久化的方式

                   appendfsync always


      三、###### Sentinel Config(sentinel.conf,192.168.127.129 Slave從服務器)服務器

          
          3.1、 ### Port 設置:

                port 26379  //哨兵端口號保持不變,能夠修改,可是我沒有修改


          3.2、### dir 設置:

                dir /root/application/program/redis/sentinel/  //哨兵程序的日誌路徑


          3.3、### Sentinel Monitor 設置:

                sentinel monitor mymaster  192.168.127.129 6379 1


          3.4、### Down-After-Milliseconds 設置:

                sentinel down-after-milliseconds mymaster 5000

                //哨兵程序每5秒檢測一次Master是否正常


          3.5、### Parallel-Syncs 設置:

               sentinel parallel-syncs mymaster 1


          3.5、### Failover-Timeout 設置:

               sentinel failover-timeout mymaster 60000


          3.5、### 啓動:redis-sentinel

                   redis-server sentinel.conf --sentinel & //(&有這能夠Ctrl +C退到命令行,沒有這個就直接退出哨兵進程)

                   redis-sentinel /path/to/sentinel.conf & //對於 redis-sentinel 程序, 你能夠用如下命令來啓動 Sentinel 系統


          3.6、### 關閉:redis-sentinel

                  pkill redis-server   //這個會關掉Redis服務器和Sentinel(哨兵)進程

                  kill 進程號     //能夠關掉指定進程號的進程


      四、###### 模式測試


               4.一、在Sentinel.conf配置文件設置 sentinel monitor:

                        

               4.二、在Sentinel.conf配置文件設置 sentinel down-after-milliseconds:

                          

               4.三、在Sentinel.conf配置文件設置 sentinel parallel-syncs:

                          

               4.四、Master 主服務器的配置詳情:

                         

               4.五、Slave 從服務器配置詳情:

                        

               4.六、啓動Sentinel(哨兵)進程,開始對Master主服務器進行監控:

架構

                         


               4.七、咱們人爲模仿Master主服務器宕機:

app

                          

               4.八、實現Master主服務器和Slave從服務器的切換:

運維

                         

               4.九、主從切換後,主服務器變成了Slave 從服務器,詳情以下:

tcp

                           

               4.十、主從切換後,從服務器變成了Master 主服務器,詳情以下:

                         

           注意:

                ① INFO
                    sentinel的基本狀態信息

               ②SENTINEL masters
                   列出全部被監視的主服務器,以及這些主服務器的當前狀態

               ③ SENTINEL slaves
                   列出給定主服務器的全部從服務器,以及這些從服務器的當前狀態

               ④SENTINEL get-master-addr-by-name
                    返回給定名字的主服務器的 IP 地址和端口號

               ⑤SENTINEL reset
                    重置全部名字和給定模式 pattern 相匹配的主服務器。重置操做清除主服務器目前的全部狀態, 包括正在執行中的故障轉移, 並移除目前已經發現和關聯的, 主服務器的全部從服務器和 Sentinel 。

               ⑥SENTINEL failover
                   當主服務器失效時, 在不詢問其餘 Sentinel 意見的狀況下, 強制開始一次自動故障遷移,可是它會給其餘sentinel發送一個最新的配置,其餘sentinel會根據這個配置進行更新


4、主觀下線和客觀下線

           下面咱們來解釋一下兩個「下線」的概念,一個是「主觀下線」,另外一個就是「客觀下線」。

            主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器作出的下線判斷。

            客觀下線(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 命令的有效回覆能夠是如下三種回覆的其中一種:

               一、返回 +PONG 。

               二、返回 -LOADING 錯誤。

              三、返回 -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(哨兵)進程在將它們判斷爲下線前不須要進行協商,因此Slave從服務器或者其餘 Sentinel(哨兵)進程永遠不會達到「客觀下線」條件。

            只要有一個 Sentinel(哨兵)進程發現某個主服務器進入了「客觀下線」狀態,這個 Sentinel(哨兵)進程就可能會被其餘 Sentinel(哨兵)進程推選出,並對失效的主服務器執行自動故障遷移操做。

5、Sentinel(哨兵)配置文件簡介

          在Redis的源碼中包含了一個名爲 sentinel.conf 的文件, 這個文件就是帶有註釋的Sentinel(哨兵)的配置文件的示例。

          若是想要運行一個「哨兵」程序,如下配置項是最少配置:

            sentinel monitor mymaster 127.0.0.1 6379 1

            sentinel down-after-milliseconds mymaster 60000

            sentinel failover-timeout mymaster 180000

            sentinel parallel-syncs mymaster 1

          第一行配置表示 Sentinel(哨兵)進程去監視一個名爲 mymaster 的主服務器,這個主服務器的 IP 地址爲 127.0.0.1 , 端口號爲 6379,而將這個主服務器判斷爲失效至少須要 1 個 Sentinel(哨兵)進程的贊成。若是在架構系統中已經配置類多個Sentinel(哨兵)進程,在贊成「Master主服務器」下線的 Sentinel(哨兵)進程的數量不達標的狀況下,Sentinel(哨兵)進程就不會執行自動故障遷移。在設置多Sentinel(哨兵)進程的狀況下,不管設置多少個 Sentinel(哨兵)進程贊成才能判斷一個服務器失效,一個 Sentinel 都須要得到架構系統中多數 Sentinel(哨兵)進程的支持, 才能發起一次自動故障遷移,並預留一個給定的配置紀元 (configuration Epoch ,一個配置紀元就是一個新主服務器配置的版本號)。若是您只配置了一個Sentinel(哨兵)進程來作監控,那一個Sentinel(哨兵)進程也能夠決定「Master主服務器」是否下線。

           其餘選項的基本格式以下:sentinel <選項的名字> <主服務器的名字> <選項的值>

           配置選項的解釋以下:

            一、down-after-milliseconds : Sentinel(哨兵)進程判斷服務器已經掉線所需的毫秒數。

                若是被監控的服務器在給定的毫秒數以內,並無返回 Sentinel(哨兵)進程發送的 PING 命令的回覆,或者返回一個錯誤,那麼 Sentinel(哨兵)進程將這個服務器標記爲主觀下線(subjectively down,簡稱 SDOWN )。若是在架構系統中配置了多個Sentinel(哨兵)進程的狀況下,只有一個Sentinel(哨兵)進程將服務器標記爲主觀下線並不必定會引發服務器的自動故障遷移,只有在足夠數量的 Sentinel(哨兵)進程都將一個服務器標記爲主觀下線以後,服務器纔會被標記爲客觀下線(objectively down, 簡稱 ODOWN ),這時纔回執行自動故障遷移。另一種狀況是,在架構系統中只配置了一個Sentinel(哨兵)進程的話,那這Sentinel(哨兵)進程也能夠決定被監控的服務器的是否「下線」。

                將服務器標記爲客觀下線所需的 Sentinel(哨兵)進程數量由對主服務器的配置決定。


           二、parallel-syncs :在執行故障轉移時,最多能夠有多少個從服務器同時對新的主服務器進行同步,這個數字越小,完成故障轉移所需的時間就越長。

               若是「Slave從服務器」被設置爲容許使用過時數據集(參見對 redis.conf 文件中對 slave-serve-stale-data 選項的說明),那麼你可能不但願全部「Slave從服務器」都在同一時間向新的「Master主服務器」發送同步請求, 由於儘管複製過程的絕大部分步驟都不會阻塞「Slave從服務器」,但「Slave從服務器」在載入「Master主服務器」發來的 RDB 文件時, 仍然會形成「Slave從服務器」在一段時間內不能處理命令請求,若是所有「Slave從服務器」一塊兒對新的「Master主服務器」進行同步, 那麼就可能會形成全部「Slave從服務器」在短期內所有不可用的狀況出現。

               你能夠經過將這個值設爲 1 來保證每次只有一個Slave從服務器處於不能處理命令請求的狀態。

           三、failover-timeout:實現主從切換,完成故障轉移的所須要的最大時間值。若Sentinel(哨兵)進程在該配置值內未能完成故障轉移的操做(即故障時master/slave自動切換),則認爲本次故障轉移操做失敗。

           四、notification-script: 指定Sentinel(哨兵)進程檢測到Master-Name所指定的「Master主服務器」的實例異常的時候,所要調用的報警腳本。該配置項可選,但線上系統建議配置。

6、哨兵模式的優缺點

       優勢:

          一、哨兵集羣模式是基於主從模式的,全部主從的優勢,哨兵模式一樣具備。

          二、主從能夠切換,故障能夠轉移,系統可用性更好。

          三、哨兵模式是主從模式的升級,系統更健壯,可用性更高。

       缺點:
       
          一、Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。爲避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源形成了很大的浪費。


7、結束

           今天就寫到這裏了,Redis的哨兵模式是以主從模式爲基礎的,因此說,主從模式擁有的一些缺點,在哨兵模式下也具備。哨兵模式主要是監控Master主服務器的運行狀況,固然也會監控Slave從服務器的運行狀況,若是Master主服務器發生了故障,該模式能夠保證Slave從服務器順利升級爲Master主服務器繼續提供服務,以此提升系統的高可用性。雖然哨兵模式比主從模式提升了很多系統的高可用性,可是該模式不能水平擴容,不能動態的增、刪節點,這也是限制哨兵模式普遍應用的主要緣由。Redis也看到了這個狀況,所在在Redis的3.x之後的版本提供了一個更增強大集羣模式,那就是Cluster集羣模式,這個模式也是咱們下一篇文章的主題。分佈式

相關文章
相關標籤/搜索