Redis 高可用架構最佳實務
一、前言
2017 年 5 月 13 日,應用效能管理大講堂廣州站圓滿落幕,其中來自三七互娛的 DBA 溫國兵在會場與各位進行了精彩的 Redis 技術分享。
Redis 是一個開源的使用 ANSI C 語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的 API。
如今,互連網業務的資料正以更快的速度在增長,資料類型越來越豐富,這對資料處理的速度和能力提出了更高要求。Redis 是一種開源的記憶體非關係型資料庫,給開發人員帶來的體驗是顛覆性的。在自始至終的設計過程中,都充分考慮高效能,這使得 Redis 成為當今速度最快的 NoSQL 資料庫。
考慮高效能的同時,高可用也是很重要的考慮因素。互連網 7x24 無間斷服務,在故障期間以最快的速度 Failover,能給企業帶來最小的損失。
那麼,在實際應用中,都有哪些高可用架構呢。架構之間有何優劣。我們應該怎麼取捨。有哪些最佳實務。
二、Sentinel 原理
在講解 Redis 高可用方案之前,我們先來看看 Redis Sentinel 原理(https://redis.io/topics/sentinel)是怎麼樣的。
Sentinel 叢集通過給定的設定檔發現 master,啟動時會監控 master。通過向 master 發送 info 資訊獲得該伺服器下面的所有從伺服器。
Sentinel 叢集通過命令串連向被監視的主從伺服器發送 hello 資訊 (每秒一次),該資訊包括 Sentinel 本身的 IP、連接埠、id 等內容,以此來向其他 Sentinel 宣告自己的存在。
Sentinel 叢集通過訂閱串連接收其他 Sentinel 發送的 hello 資訊,以此來發現監視同一個主伺服器的其他 Sentinel;叢集之間會互相建立命令串連用於通訊,因為已經有主從伺服器作為發送和接收 hello 資訊的中介,Sentinel 之間不會建立訂閱串連。
Sentinel 叢集使用 ping 命令來檢測執行個體的狀態,如果在指定的時間內(down-after-milliseconds)沒有回複或則返回錯誤的回複,那麼該執行個體被判為下線。
當 failover 主備切換被觸發後,failover 並不會馬上進行,還需要 Sentinel 中的大多數 Sentinel 授權後才可以進行 failover,即進行 failover 的 Sentinel 會去獲得指定 quorum 個的 Sentinel 的授權,成功後進入 ODOWN 狀態。如在 5 個 Sentinel 中配置了 2 個 quorum,等到 2 個 Sentinel 認為 master 死了就執行 failover。
Sentinel 向選為 master 的 slave 發送 SLAVEOF NO ONE 命令,選擇 slave 的條件是 Sentinel 首先會根據 slaves 的優先順序來進行排序,優先順序越小排名越靠前。如果優先順序相同,則查看複製的下標,哪個從 master 接收的複製資料多,哪個就靠前。如果優先順序和下標都相同,就選擇進程 ID 較小的。
Sentinel 被授權後,它將會獲得宕掉的 master 的一份最新配置版本號碼 (config-epoch),當 failover 執行結束以後,這個版本號碼將會被用於最新的配置,通過廣播形式通知其它 Sentinel,其它的 Sentinel 則更新對應 master 的配置。
1 到 3 是自動探索機制:
以 10 秒一次的頻率,向被監視的 master 發送 info 命令,根據回複擷取 master 當前資訊。
以 1 秒一次的頻率,向所有 redis 伺服器、包含 Sentinel 在內發送 PING 命令,通過回複判斷伺服器是否線上。
以 2 秒一次的頻率,通過向所有被監視的 master,slave 伺服器發送當前 Sentinel master 資訊的訊息。
4 是檢測機制,5 和 6 是 failover 機制,7 是更新配置機制。[1]
三、Redis 高可用架構
講解完 Redis Sentinel 原理之後,接下來講解常用的 Redis 高可用架構。
Redis Sentinel 叢集 + 內網 DNS + 自訂指令碼
Redis Sentinel 叢集 + VIP + 自訂指令碼
封裝用戶端直連 Redis Sentinel 連接埠
JedisSentinelPool,適合 Java
PHP 基於 phpredis 自行封裝
Redis Sentinel 叢集 + Keepalived/Haproxy
Redis M/S + Keepalived
Redis Cluster
Twemproxy
Codis
接下來配合圖文逐個講解。
1、Redis Sentinel 叢集 + 內網 DNS + 自訂指令碼
Redis Sentinel 叢集 + 內網 DNS + 自訂指令碼
上圖是已經線上上環境應用的方案。底層是 Redis Sentinel 叢集,代理著 Redis 主從,Web 端串連內網 DNS 提供服務。內網 DNS 按照一定的規則分配,比如 xxxx.redis.cache/queue.port.xxx.xxx,第一個段表示業務簡寫,第二個段表示這是 Redis 內網網域名稱,第三個段表示 Redis 類型,cache 表示緩衝,queue 表示隊列,第四個段表示 Redis 連接埠,第五、第六個段表示內網主網域名稱。
當主節點發生故障,比如機器故障、Redis 節點故障或者網路不可達,Sentinel 叢集會調用 client-reconfig-script 配置的指令碼,修改對應連接埠的內網網域名稱。對應連接埠的內網網域名稱指向新的 Redis 主節點。
優點:
秒級切換,在 10s 內完成整個切換操作
指令碼自訂,架構可控
對應用透明,前端不用擔心後端發生什麼變化
缺點:
維護成本略高,Redis Sentinel 叢集建議投入 3 台機器以上
依賴 DNS,存在解析延時
Sentinel 模式存在短時間的服務不可用
服務通過外網訪問不可採用此方案
2、Redis Sentinel 叢集 + VIP + 自訂指令碼
Redis Sentinel 叢集 + VIP + 自訂指令碼
此方案和上一個方案相比,略有不同。第一個方案使用了內網 DNS,第二個方案把內網 DNS 換成了虛擬 IP。底層是 Redis Sentinel 叢集,代理著 Redis 主從,Web 端通過 VIP 提供服務。在部署 Redis 主從的時候,需要將虛擬 IP 綁定到當前的 Redis 主節點。當主節點發生故障,比如機器故障、Redis 節點故障或者網路不可達,Sentinel 叢集會調用 client-reconfig-script 配置的指令碼,將 VIP 漂移到新的主節點上。
優點:
秒級切換,在 5s 內完成整個切換操作
指令碼自訂,架構可控
對應用透明,前端不用擔心後端發生什麼變化
缺點:
維護成本略高,Redis Sentinel 叢集建議投入 3 台機器以上
使用 VIP 增加維護成本,存在 IP 混亂風險
Sentinel 模式存在短時間的服務不可用
3.3 封裝用戶端直連 Redis Sentinel 連接埠
3、封裝用戶端直連 Redis Sentinel 連接埠