故障轉移
因爲Redis支持主從複製,並且主從服務器的數據完全一致。因此,當主服務器因故障下線時,將它的其中一臺從服務器轉換爲主服務器,並使用新的主服務器繼續處理命令請求,這樣整個系統就可以繼續運行,不比僅因爲主服務器下線而停機。這種使用正常服務器替換下線服務器以維持系統正常運轉的操作,一般被稱爲故障轉移(failover)。
手動故障轉移
因爲Redis支持主從複製特性,所以我們同樣可以對下線的Redis主服務器實施故障轉移,假設現在有一個主服務器 127.0.0.1:6379
(簡稱 6379),它有兩個從服務器 127.0.0.1:6380
(簡稱 6380) 和 127.0.0.1:6381
(簡稱 6381),對主服務器實施故障轉移的步驟如下:
- 先向 6380 發送命令
REPLICAOF no one
,將它轉換爲主服務器; - 然後向另一個從服務器6381發送命令
REPLICAOF 127.0.0.1 6380
,讓它去複製新的主服務器 6380;
具體如下圖所示:
Sentinel(哨兵)
當Redis主從複製結構比較複雜,比如一主多從的情況下,監視多臺Redis服務器,並在有需要的時候對下線的主服務器實施故障轉移,並不是一件容易的事情。爲此,Redis服務器提供了自動化的故障轉移功能,提高主從服務器的可用性,Redis爲用戶提供了 Redis Sentinel 工具,Sentinel(哨兵) 可以通過心跳檢測的方式監視多個主服務器以及它們下屬的所有從服務器,並在某個主服務器下線的時候自動對其實施故障轉移。
啓動Sentinel
在瞭解了Redis Sentinel的基本作用之後,現在讓我們來學習一下如何啓動Redis Sentinel並讓它去監視指定的主服務器。
Redis Sentinel的程序文件名爲 redis-sentinel
,它通常和普通的Redis服務器 redis-server
位於同一個文件夾。因爲用戶需要在配置文件中指定想要被 Sentinel 監視的主服務器,並且 Sentinel 也需要在配置文件中寫入信息以及記錄主從服務器的狀態,所以用戶在啓動 Sentinel 的時候必須傳入一個 可寫 的配置文件作爲參數,如下:
redis-sentinel /etc/sentinel.conf
如果用戶給定的配置文件是不可寫的,那麼 Sentinel 將放棄啓動並報告一個錯誤
一個 Sentinel 配置文件至少需要包含以下選項,用於指定 Sentinel 要監視的主服務器:
sentinel monitor <master-name> <ip> <port> <quorum>
其中 <master-name> 參數用於指定主服務器的名字,這個名字在執行各種 Sentinel 操作的時候經常會用到;ip 參數和 port 參數用於指定主服務器的IP地址和端口號;而 quorum 參數則用於指定判斷這個主服務器下線所需要的 Sentinel 數量。
sentinel monitor mymaster 127.0.0.1 6379 1
Sentinel 在開始監視一個主服務器之後,就會獲取被監視主服務器的從服務器名單,並根據名單對各個從服務器實施監視,整個過程完全自動,所以用戶只需要輸入待監視的主服務器的地址就可以了,並不需要輸入從服務器的地址。
因爲Redis Sentinel實際上就是一個運行與特殊模式下的Redis服務器,所以用戶也可以使用命令 redis-server sentinel.conf --sentinel 去啓動一個Sentinel:這裏的 --sentinel 參數用於指示Redis服務器進入Sentinel模式,從而變成一個Redis Sentinel而不是普通的Redis服務器。 |
一個Sentinel可以監視任意數量的主服務器,而不是僅僅監視一個主服務器。如果用戶想要使用Sentinel去監視多個主服務器,那麼只需要在配置文件中指定多個sentinel monitor選項即可。 |
Sentinel在對下線的主服務器實施故障轉移之後,仍然會繼續對它進行心跳檢測,當這個服務器重新上線的時候,Sentinel將把它轉換爲當前主服務器的從服務器。 |
用戶可以通過 replica-priority 配置選項來設置各個從服務器的優先級,優先級高的從服務器在 Sentinel 選擇新主服務器的時候會優先被選擇。replica-priority的默認值爲100,這個值越小,從服務器的優先級越高。replica-priority值爲0的從無服務器永遠不會被選爲主服務器,用戶可以通過這一設置將不適合用作主服務器的從服務器排除在新主服務器的候選名單之外。 |
當Sentinel需要在多個從服務器中選擇一個作爲新的主服務器時,首先會根據以下規則從候選名單中剔除不符合條件的從服務器: 1) 否決所有已經下線以及長時間沒有回覆心跳檢測的疑似已下線的從服務器。 2) 否決所有長時間沒有與主服務器通信的,數據狀態過時的從服務器。 3) 否決所有優先級爲0的從服務器。 然後根據以下規則,在剩餘的候選從服務器中選出新的主服務器: 1) 優先級最高的從服務器獲勝。 2) 如果優先級最高的從服務器有兩個或以上,那麼複製偏移量最大的那個從服務器獲勝。 3) 如果符合上述兩個條件的從服務器有兩個或以上,那麼選出它們當中運行ID最小的那一個。 |
Sentinel網絡
在實際應用中,只使用單個 Sentinel 監視主從服務器並不合適,因爲:
- 單個 Sentinel 可能會形成單點故障,當唯一的 Sentinel 出現故障時,針對主從服務器的自動故障轉移將無法實施。
- 單個 Sentinel 可能會因爲網絡故障而無法獲得主服務器的相關信息,並因此錯誤的將主服務器判斷爲下線,繼而執行實際上並無必要的故障轉移操作。
爲了避免 Sentinel 單點故障,並能夠給出真實有效的判斷結果,我們可以使用多個 Sentinel 組建一個分佈式 Sentinel 網絡,網絡中的各個 Sentinel可以通過互通消息來更加準確地判斷服務器的狀態。
當 Sentinel 網絡中的其中一個 Sentinel 認爲某個主服務器已經下線時,它會將這個主服務器標記爲主觀下線,然後詢問網絡中的其他 Sentinel,是否也認爲該服務器已下線。當同意主服務器下線的 Sentinel 數量達到 sentinel monitor
配置選項中 quorum
參數所指定的數量時,Sentinel 就會將相應的主服務器標記爲客觀下線,然後開始對其進行故障轉移。
Sentinel管理命令
Redis爲 Sentinel 提供了相應的管理命令,用於對 Sentinel 執行各種各樣的管理操作。
Sentinel masters:獲取所有被監視的主服務器的信息
通過向 Sentinel 發送以下命令,用戶可以獲得 Sentinel 正在監視的所有主服務器的相關信息:
Sentinel masters
命令返回的各個字段的及其意義:
Sentinel master:獲取指定被監視主服務器的信息
如果想要獲取特定主服務器的信息而不是主服務器的信息,可以使用以下命令代替 Sentinel masters
命令:
Sentinel master <master-name>
這個命令只會返回用戶指定的主服務器的相關信息。
Sentinel slaves:獲取被監視主服務器的從服務器信息
通過使用以下命令,可以讓 Sentinel 返回指定的主服務器屬下所有從服務器的相關信息:
Sentinel slaves <master-name>
命令返回的字段及其意義:
Sentinel sentinels:獲取其他Sentinel的相關信息
用戶可以通過執行以下命令,獲取監視同一個主服務器的其他所有Sentinel的相關信息:
Sentinel sentinels <master-name>
命令返回的字段及其含義:
Sentinel get-master-addr-by-name:獲取給定的主服務器的IP地址和端口號
用戶可以通過以下命令,通過給定的主服務器的名字來獲取該服務器的IP地址和端口號:
Sentinel get-master-addr-by-name <master-name>
Sentinel reset:重置主服務器狀態
Sentinel reset 命令接受一個glob風格的模式作爲參數,接收到該命令的 Sentinel 將重置所有與給定模式相匹配的主服務器:
Sentinel reset <pattern>
命令將返回被重置主服務器的數量作爲返回值。接收到Sentinel reset 命令的 Sentinel 除了會清理被匹配主服務器的相關信息之外,還會遺忘被匹配主服務器目前已有的所有從服務器,以及正在監視被匹配主服務器的所有其他 Sentinel。然後,這個 Sentinel將會重新搜索正在監視被匹配主服務器的其他Sentinel,以及該服務器屬下的各個從服務器,並與它們重新建立連接。
Sentinel failover:強制執行故障轉移
通過執行以下命令,可以強制對指定的主服務器實施故障轉移:
Sentinel failover <master-name>
接收到這一命令的Sentinel 會直接對主服務器執行故障轉移操作,而不會像平時那樣,先在Sentinel網絡中投票,然後再根據投票結果決定是否執行故障轉移操作。
Sentinel ckquorum:檢查可用的Sentinel數量
通過以下命令,檢查Sentinel 網絡中當前可用的Sentinel數量是否達到了判斷主服務器客觀下線並實施故障轉移所需的數量:
Sentinel ckquorum <master-name>
Sentinel flushconfig:強制寫入配置文件
用戶可以通過向 Sentinel 發送以下命令,讓 Sentinel 將它的配置文件重新寫入硬盤中:
Sentinel flushconfig
因爲Sentinel在被監視服務器的狀態發生變化時就會自動重寫配置文件,所以這個命令的作用就是在配置文件基於某些原因或錯誤而丟失時,立即生成一個新的配置文件。
在線配置 Sentinel
從Redis 2.8.4版本開始爲 Sentinel 命令添加了一組子命令,這些子命令可以在線修改Sentinel對於監視主服務器的配置選項,並把修改後的配置選項保存到配置文件中,整個過程完全不需要停止 Sentinel,也不需要手動修改配置文件。
Sentinel monitor:監視給定的主服務器
通過以下命令,用戶可以讓 Sentinel 開始監視一個新的主服務器:
Sentinel monitor <master-name> <ip> <port> <quorum>
Sentinel monitor命令本質上就是 sentinel monitor配置選項的命令版本,當我們想要讓 Sentinel 監視一個新的主服務器,但是又不想重啓 Sentinel 並手動修改配置文件時,就可以使用該命令。
Sentinel remove:取消給定主服務器的監視
當用戶想要在線取消Sentinel對某個主服務器的監視時,可以使用以下命令:
Sentinel remove <master-name>
接收到這個命令的Sentinel會停止對給定主服務器的監視,並刪除Sentinel內部以及Sentinel配置文件中與給定主服務器有關的信息,然後返回OK,表示執行成功。
Sentinel set:修改Sentinel配置選項的值
通過使用以下命令,用戶可以在線修改Sentinel配置文件中與主服務器有關的配置選項:
Sentinel set <master-name> <option> <value>
只要是Sentinel配置文件中與主服務器有關的配置選項,都可以使用 Sentinel set 命令在線進行配置,命令在執行成功後返回OK表示成功。
在線配置命令的注意事項
需要注意的是,以上介紹的各個在線配置命令只會對接收到命令的單個Sentinel起效,並不會對同一個Sentinel網絡的其他Sentinel產生影響。