1. 程式人生 > >redis主從複製及切換

redis主從複製及切換

現在我的系統用redis做快取伺服器,redis是一個單點,當一臺機器巖機的時候,redis的服務完全停止,這時就會影響其他服務的正常執行,所以我們要做的是redis主從複製及主動切換,這就是redis叢集的概念

首先介紹下怎麼樣做redis主備切換,需要用到redis的sentinel做一個主從切換的叢集管理。redis主從服務(1個master,多個salve),然後通過redis官方的監控工具Sentinel(哨兵),對每個節點進行監控,實現自動故障遷移,即master死掉,將salve升級為master。基本原理是:心跳機制+投票裁決。

Redis 的 Sentinel 系統用於管理多個 Redis 伺服器(instance), 該系統執行以下三個任務:

監控(Monitoring): Sentinel 會不斷地檢查你的主伺服器和從伺服器是否運作正常。

提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過API 向管理員或者其他應用程式傳送通知。

自動故障遷移(Automatic failover): 當一個主伺服器不能正常工作時,Sentinel 會開始一次自動故障遷移操作, 它會將失效主伺服器的其中一個從伺服器升級為新的主伺服器, 並讓失效主伺服器的其他從伺服器改為複製新的主伺服器;當客戶端試圖連線失效的主伺服器時, 叢集也會向客戶端返回新主伺服器的地址, 使得叢集可以使用新主伺服器代替失效伺服器。

Redis Sentinel 是一個分散式系統, 你可以在一個架構中執行多個 Sentinel 程序(progress), 這些程序使用流言協議(gossip protocols)來接收關於主伺服器是否下線的資訊, 並使用投票協議(agreementprotocols)來決定是否執行自動故障遷移,以及選擇哪個從伺服器作為新的主伺服器。

雖然 Redis Sentinel 釋出為一個單獨的可執行檔案 redis-sentinel, 但實際上它只是一個執行在特殊模式下的 Redis 伺服器, 你可以在啟動一個普通 Redis 伺服器時通過給定 --sentinel 選項來啟動Redis Sentinel 。

 環境準備:10.161.47.168 6380 主

            10.161.47.168 6381 從

      Sentinel :10.161.47.168 26380

備註:若是3臺不同的機器,首先要保證內網埠互通。

主從複製配置

主redis配置檔案可以不動

從redis配置檔案需要新增:slaveof 10.161.47.1686380
若master配置了密碼則slave也要配置相應的密碼引數否則無法進行正常複製的,新增:masterauth mstpassword 
 驗證一:redis-cli -h 10.161.47.168 -p 6380 info replication
         redis-cli -h 10.161.47.168 -p 6381 info replication
看到如下圖顯示,說明配置成功:
# redis-cli -h 10.161.47.168 -p 6380 info replication
# Replication
role:slave
master_host:10.161.47.168
master_port:6381
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:13544
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# redis-cli -h 10.161.47.168 -p 6381 info replication   
# Replication
role:master
connected_slaves:1
slave0:ip=10.161.47.168,port=6380,state=online,offset=14841,lag=0
master_repl_offset:14841
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:14840

  驗證二:可以在主redis插入資料測試,看看從redis可不可以檢視

主備切換

 需要配置sentinel ,在redis的安裝目錄下有sentinel的配置檔案,我們備份一下,在進行編輯。

vim /etc/redis/sentinel_26380.conf

##redis-0

##sentinel例項之間的通訊埠

port 26380
daemonize yes  守護程序啟動
logfile "/var/log/redis/sentinel.log"
sentinel monitor master1 10.161.47.168 6380 2
      #配置master名、ip、port、需要多少個sentinel才能判斷[客觀下線
sentinel down-after-milliseconds master1 30000      #配置sentinel向master發出ping,最大響應時間、超過則認為主觀下線
sentinel parallel-syncs master1 1                   
#配置在進行故障轉移時,執行多少個slave進行資料備份同步(越少速度越快)
sentinel failover-timeout master1 180000            #配置當出現failover時下一個sentinel與上一個sentinel對[同一個master監測的時間間隔](最後設定為客觀下線)
 

#master2  可以新增多組主從的redis監聽

特殊配置:

min-slaves-to-write 1

min-slaves-max-lag 10

通過上面的配置,當一個redis是master時,如果它不能向至少一個slave寫資料(上面的min-slaves-to-write指定了slave的數量),它將會拒絕接受客戶端的寫請求。由於複製是非同步的,master無法向slave寫資料意味著slave要麼斷開連線了,要麼不在指定時間內向master傳送同步資料的請求了(上面的min-slaves-max-lag指定了這個時間)。

配置檔案配置好之後,啟動 redis-sentinel /etc/redis/sentinel_26380.conf

檢視日誌:+slave slave 10.161.47.168:6381 10.161.47.168 6381 @ master-210.161.47.168 6380

  驗證主備切換:

  1首先檢視redis-cli -p 26380 info Sentinel

  顯示:# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

master0:name=master-2,status=ok,address=10.161.47.168:6380,slaves=1,sentinels=1

可以看到6380埠為master。

現在關閉master節點,即kill掉master程序

2 檢視sentinel服務,發現埠6381升級為master節點,這時sentinel完成故障自動切換。

redis-cli -p 26380 info Sentinel

# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

master0:name=master-2,status=ok,address=10.161.47.168:6381,slaves=1,sentinels=1

3、 啟動剛才被shutdown的6380服務並檢視,發現它變成了slave服務

   redis-cli -h 10.161.47.168 -p 6380 inforeplication

# Replication

role:slave

master_host:10.161.47.168

master_port:6381

master_link_status:up

master_last_io_seconds_ago:2

master_sync_in_progress:0

slave_repl_offset:13544

slave_priority:100

slave_read_only:1

connected_slaves:0

master_repl_offset:0

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

到此主從複製切換就做好了。

每個Sentinel例項都執行的定時任務

1. 每個Sentinel 以每秒鐘一次的頻率向它所知的主伺服器、從伺服器以及其他 Sentinel 例項傳送一個 PING 命令。

2. 如果一個例項(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值,那麼這個例項會被 Sentinel 標記為主觀下線。 一個有效回覆可以是:+PONG 、 -LOADING 或者-MASTERDOWN 。

3. 如果一個主伺服器被標記為主觀下線, 那麼正在監視這個主伺服器的所有Sentinel 要以每秒一次的頻率確認主伺服器的確進入了主觀下線狀態。

4. 如果一個主伺服器被標記為主觀下線, 並且有足夠數量的 Sentinel (至少要達到配置檔案指定的數量)在指定的時間範圍內同意這一判斷,那麼這個主伺服器被標記為客觀下線。

5. 在一般情況下, 每個 Sentinel 會以每10 秒一次的頻率向它已知的所有主伺服器和從伺服器傳送 INFO 命令。 當一個主伺服器被 Sentinel 標記為客觀下線時, Sentinel 向下線主伺服器的所有從伺服器傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次。

6. 當沒有足夠數量的 Sentinel 同意主伺服器已經下線, 主伺服器的客觀下線狀態就會被移除。當主伺服器重新向 Sentinel 的 PING 命令返回有效回覆時,主伺服器的主管下線狀態就會被移除。

服務日誌說明

Sentinel服務啟動後會列印一些相關日誌資訊,以下是相關日誌特殊字元說明:

+reset-master <instance details> :主伺服器已被重置。

+slave <instance details> :一個新的從伺服器已經被 Sentinel 識別並關聯。

+failover-state-reconf-slaves <instancedetails> :故障轉移狀態切換到了reconf-slaves 狀態。

+failover-detected <instance details>:另一個 Sentinel 開始了一次故障轉移操作,或者一個從伺服器轉換成了主伺服器。

+slave-reconf-sent <instance details>:領頭(leader)的 Sentinel 向例項傳送了 SLAVEOF 命令,為例項設定新的主伺服器。

+slave-reconf-inprog <instancedetails> :例項正在將自己設定為指定主伺服器的從伺服器,但相應的同步過程仍未完成。

+slave-reconf-done <instance details>:從伺服器已經成功完成對新主伺服器的同步。

-dup-sentinel <instance details> :對給定主伺服器進行監視的一個或多個 Sentinel 已經因為重複出現而被移除 —— 當 Sentinel 例項重啟的時候,就會出現這種情況。

+sentinel <instance details> :一個監視給定主伺服器的新 Sentinel 已經被識別並新增。

+sdown <instance details> :給定的例項現在處於主觀下線狀態。

-sdown <instance details> :給定的例項已經不再處於主觀下線狀態。

+odown <instance details> :給定的例項現在處於客觀下線狀態。

-odown <instance details> :給定的例項已經不再處於客觀下線狀態。

+new-epoch <instance details> :當前的紀元(epoch)已經被更新。

+try-failover <instance details> :一個新的故障遷移操作正在執行中,等待被大多數 Sentinel 選中(waiting to be elected bythemajority)。

+elected-leader <instance details> :贏得指定紀元的選舉,可以進行故障遷移操作了。

+failover-state-select-slave <instancedetails> :故障轉移操作現在處於select-slave 狀態 ——Sentinel 正在尋找可以升級為主伺服器的從伺服器。

no-good-slave <instance details> :Sentinel操作未能找到適合進行升級的從伺服器。Sentinel 會在一段時間之後再次嘗試尋找合適的從伺服器來進行升級,又或者直接放棄執行故障轉移操作。

selected-slave <instance details> :Sentinel 順利找到適合進行升級的從伺服器。

failover-state-send-slaveof-noone<instance details> :Sentinel 正在將指定的從伺服器升級為主伺服器,等待升級功能完成。

failover-end-for-timeout <instancedetails> :故障轉移因為超時而中止,不過最終所有從伺服器都會開始複製新的主伺服器(slaves willeventually be configured to replicate with the newmaster anyway)。

failover-end <instance details> :故障轉移操作順利完成。所有從伺服器都開始複製新的主伺服器了。

+switch-master <master name><oldip> <oldport><newip> <newport> :配置變更,主伺服器的IP 和地址已經改變。 這是絕大多數外部使用者都關心的資訊。