1. 程式人生 > >Redis 高可用部署

Redis 高可用部署

Redis 高可用

  • Redis 高可用原理:
    Redis使用sentinel機制來實現高可用,sentinel是另外一個集群,主要是用來監控所有的Redis服務器,所以主節點和從節點,監控方式仍然使用的是ping指令,sentinel每隔1秒向master發送【ping】,如果在一段時間內沒有收到【pong】或者收到無效回復,則認為master下線。
    sentinel對下線有兩種定義:
    a.主觀下線(sdown):sentinel實例本身對服務實例的判斷
    b.客觀下線(odown):多個sentinel實例對同一個服務SDOWN的狀態做出協商後的判斷,只有master才可能在odown狀態 。
    簡單的說,一個sentinel單獨做出的判斷只能是sdown,是沒有任何官方效力的,只有多個sentinel大家商量好,得到一致,才能將某個master狀態置為odown,只有確定master odown狀態後,才能做後續fail over的操作。

    如果發現主的離線了,你不用告訴它哪個是主的,它會獲取服務器信息,了解誰是主誰是從,你只要告訴它誰是主的就行了,它會從主上獲取有哪些從,如果主down,它會從從中選一個當成為新的主節點,它能夠實現監控整個主從復制架構,一旦發現主down了,會自動從多個從中選擇一個從的提升為新的主,那麽此前從節點連的主節點是原來的老主,原來的主節點不在了怎麽辦,sentinel告訴客戶端新的主是誰 ,向客戶端發送slaveof指定讓從節點重新選擇主節點。
    如果sentinel連不主節點或者sentinel本身故障了怎麽辦,所以sentinel需要做一個集群。由集群中的每個節點來共同判斷redis節點是否down了。
    Sentinel作用:管理多個redis服務實現HA
    監控: Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
    通知:當被監控的某個Redis服務器出現問題時, Sentinel可以通過API向管理員或者其他應用程序發送通知。
    自動故障轉移:當一個主服務器不能正常工作時, Sentinel會開始一次自動故障遷移操作,它會將失效主服務器的其中一個從服務器升級為新的主服務器,並讓失效主服務器的其他從服務器改為復制新的主服務器;當客戶端試圖連接失效的主服務器時,集群也會向客戶端返回新主服務器的地址,使得集群可以使用新主服務器代替失效服務器。
    流言協議,投票協議。

  • sentinel的啟動

    啟動方式有兩種:

    # 通過redis-server 的sentinel參數啟動:
    redis-servier /etc/sentinel.conf  --sentinel
    # 通過redis-sentinel命令啟動:
    redis-sentinel /etc/sentinel.conf 

    Sentinel依賴於配置文件,它必須用配置文件不停保存自已的狀態信息。
    啟動一個sentinel有以下幾個步驟:
    1,服務器自身初始化 。
    運行 redis-server 中專用於sentinel功能的代碼
    2,初始化sentinel狀態,根據給定的配置文件,初始化監控的master服務器列表
    3,創建連向master的連接。

  • sentinel專用配置文件:/etc/redis-sentinel.conf

        port 26379 
        sentinel monitor mymaster 127.0.0.1 6379 2   
         #指定要監控的master,mymaster名字,可以不指,quorum法定票數2,此處指的是sentinel的數,三個sentinel占2個,指定的sentinel同意時才認為sentinel做的決策是有效的,一般大於sentinel數量的半數。
       # 可以有多個,一組sentinel集群可以監控N個主從復制架構 
        sentinel auth-pass mymaster redis  #指定要連接的redis master密碼 
        sentinel down-after-milliseconds mymaster 30000  #至少多長時間 連不上才認為主的離線了。單位為ms,   即連接超時時長。 
        sentinel parallel-syncs 1 # 剛剛設定為新主時,允許同時有多少個從向主發起同步請求。 
        entinel failover-timeout mymaster 180000 #故障轉移的超時時長 
                   #當主故障時,把新的從提升為主,多長時間提不上就認為故障轉移失敗。 
    

    示例:
    一主兩從:
    主:10.3.1.15 6379
    從:10.3.1.15 6378
    從:10.3.1.15 6376
    Sentinel:10.3.1.17

  • 1, 在從的redis.conf 加上這句即可成為主從關系:

      slaveof <masterip> <masterport>

    2, 連接到主服務器上查看:

    127.0.0.1:6379> INFO replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=127.0.0.1,port=6378,state=online,offset=5204,lag=1
    slave1:ip=127.0.0.1,port=6376,state=online,offset=5204,lag=1
    master_repl_offset:5218
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:5217
    127.0.0.1:6379>
    #主從關系已正常

    3, 配置sentinel.conf
    sentinel.conf的配置參數上面已經描述。

    4, 在前臺啟動sentinel

    #啟動sentinel 
    ./bin/redis-sentinel /data/service/redis/sentinel.conf  
    18844:X 23 Mar 18:34:58.053 * Increased maximum number of open files to 10032 (it was originally set to 1024). 
    
                    _._                                                   
    
               _.-``__ ‘‘-._                                              
    
          _.-``    `.  `_.  ‘‘-._           Redis 3.2.11 (00000000/0) 64 bit 
    
      .-`` .-```.  ```\/    _.,_ ‘‘-._                                    
    
    (    ‘      ,       .-`  | `,    )     Running in sentinel mode 
    
    |`-._`-...-` __...-.``-._|‘` _.-‘|     Port: 26379 
    
    |    `-._   `._    /     _.-‘    |     PID: 18844 
    
      `-._    `-._  `-./  _.-‘    _.-‘                                    
    
    |`-._`-._    `-.__.-‘    _.-‘_.-‘|                                   
    
    |    `-._`-._        _.-‘_.-‘    |           http://redis.io         
    
      `-._    `-._`-.__.-‘_.-‘    _.-‘                                    
    
    |`-._`-._    `-.__.-‘    _.-‘_.-‘|                                   
    
    |    `-._`-._        _.-‘_.-‘    |                                   
    
      `-._    `-._`-.__.-‘_.-‘    _.-‘                                    
    
          `-._    `-.__.-‘    _.-‘                                        
    
              `-._        _.-‘                                            
    
                  `-.__.-‘                                                
    
    18844:X 23 Mar 18:34:58.054 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 
    
    18844:X 23 Mar 18:34:58.056 # Sentinel ID is 524c94beed78f379e4a0b3b641992449b0cdcf7f 
    
    18844:X 23 Mar 18:34:58.056 # +monitor master mymaster 10.3.1.15 6379 quorum 2 
    
    18844:X 23 Mar 18:34:58.057 * +slave slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379 
    
    18844:X 23 Mar 18:34:58.059 * +slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 
    
    #啟動完成,從控制臺上面已經找到master和slave。

    下面是連入sentinel 查看master信息:

    root@ubuntu17:$ redis-cli -h 10.3.1.17 -p 26379 
    10.3.1.17:26379> info 
    DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no‘ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to ‘no‘, and then restarting the server. 3) If you started the server manually just for testing, restart it with the ‘--protected-mode no‘ option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside. 

    如上,輸入info後報錯說是redis工作在保護模式下,通過‘CONFIG SET protected-mode no 來關閉,因為默認protected-mode 為yes。
    通過在所有的redis,即一主兩從上都加上這句話,然後在sentinel後,仍然報此錯,於是嘗試在sentinel本身的sentinel.conf文件中加入了這句,保存並重啟sentinel,然後執行info就不報錯了。

    部署成功性驗證:

    10.3.1.17:26379> INFO 
    # Sentinel 
    sentinel_masters:1 
    sentinel_tilt:0 
    sentinel_running_scripts:0 
    sentinel_scripts_queue_length:0 
    sentinel_simulate_failure_flags:0 
    master0:name=mymaster,status=ok,address=10.3.1.15:6379,slaves=2,sentinels=1 
    10.3.1.17:26379>  #mymaster是在sentinel.conf設置的master名稱。 

    sentinel專用命令:

             sentinel masters  #獲取所有監控的主 
             sentinel slaves <master name>  #列出該master的所有從節點 
             sentinel  get-master-addr-by-name <master name>根據名字來獲取地址 
             sentinel  reset    #重置所有 從頭再來 
             sentinel failover <mater name>  #手動故障轉移,並指明向哪組mater name發起手動 
    #獲取sentinel 所監控的redis master服務器信息 
    10.3.1.17:26379> sentinel masters 
    
    1)  1) "name" 
    
        2) "mymaster" 
    
        3) "ip" 
    
        4) "10.3.1.15" 
    
        5) "port" 
    
        6) "6379" 
    
        7) "runid" 
    
        8) "3520e56cadc7a3cd591da0094199d46a83771318" 
    
        9) "flags" 
    
       10) "master" 
    
       11) "link-pending-commands" 
    
       12) "0" 
    
       13) "link-refcount" 
    
       14) "1" 
    
       15) "last-ping-sent" 
    
       16) "0" 
    
       17) "last-ok-ping-reply" 
    
       18) "697" 
    
       19) "last-ping-reply" 
    
       20) "697" 
    
       21) "down-after-milliseconds" 
    
       22) "30000" 

    高可用驗證:
    當把主master 停掉,在sentinel控制臺中輸出故障轉移過程:

    62360:X 24 Mar 13:05:53.197 # +sdown master mymaster 10.3.1.15 6379  #主觀認為master已失效 
    
    62360:X 24 Mar 13:05:53.197 # +odown master mymaster 10.3.1.15 6379 #quorum 1/1  #客觀認為master已失效 
    
    62360:X 24 Mar 13:06:07.965 # +new-epoch 13  #準備進master新一紀元,第13次選舉。 
    
    62360:X 24 Mar 13:06:07.965 # +try-failover master mymaster 10.3.1.15 6379  #嘗試轉移master 
    
    62360:X 24 Mar 13:06:07.967 # +vote-for-leader 9cf767f451de09136054ccc6afc6dcc5f939b5a0 13  #投票選舉leader 
    
    62360:X 24 Mar 13:06:07.967 # +elected-leader master mymaster 10.3.1.15 6379  #之前被選舉出來的 master 
    
    62360:X 24 Mar 13:06:07.967 # +failover-state-select-slave master mymaster 10.3.1.15 6379 #Leader開始select合適的master 
    
    62360:X 24 Mar 13:06:08.034 # +selected-slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #已找到了合適的從10.3.1.15:6376為主 
    
    62360:X 24 Mar 13:06:08.034 * +failover-state-send-slaveof-noone slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #Leader 向 slave 發送“slaveof no one”指令,此時 slave 已經完成角色轉換,此 slave 即為 master 
    
    62360:X 24 Mar 13:06:08.093 * +failover-state-wait-promotion slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #等待其他 sentinel 確認 slave 
    
    62360:X 24 Mar 13:06:09.116 # +promoted-slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #確認成功 
    
    62360:X 24 Mar 13:06:09.116 # +failover-state-reconf-slaves master mymaster 10.3.1.15 6379 #開始對slaves進行reconfig 操作 
    
    62360:X 24 Mar 13:06:09.176 * +slave-reconf-sent slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379 #向指定的slave 發送“slaveof”指令,告知此 slave 跟隨新的 master 
    
    62360:X 24 Mar 13:06:10.132 * +slave-reconf-inprog slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379 開始對slaves進行reconfig 操作 

    然後進入sentinel中查看新的master:

    10.3.1.17:26379> sentinel masters 
     #可以看到master已經發生了改變
    1)  1) "name" 
    
        2) "mymaster" 
    
        3) "ip" 
    
        4) "10.3.1.15"   
    
        5) "port" 
    
        6) "6376" 
    
        7) "runid"  

    回到某個slave節點查看:

    10.3.1.15:6378> config get slaveof 
    
    1) "slaveof" 
    
    2) "10.3.1.15 6376" 
    
    10.3.1.15:6378>  

    現在把原來的master 6379啟動起來,再看下它是主還是從:

    10.3.1.15:6379> config get slaveof 
    
    1) "slaveof" 
    
    2) "10.3.1.15 6376" 
    
    #原來的master,此時已是從節點了

    現在進入新選舉出來的master查看:

    10.3.1.15:6376> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=10.3.1.15,port=6379,state=online,offset=707098,lag=1
    slave1:ip=10.3.1.15,port=6379,state=wait_bgsave,offset=0,lag=0
    master_repl_offset:707098
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:707097
    10.3.1.15:6376> 
    

    以上就是sentinel就是高可用功能,客戶端程序應該向sentinel發請求,去尋求新Master的地址 ,這時要用redis專用程序,根據sentinel反饋來聯絡新服務器。

    Redis 高可用部署