你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!

題記

Redis 是一個開源的使用 ANSI C 語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value 數據庫,並提供多種語言的 API。

你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!

如今,互聯網業務的數據正以更快的速度在增長,數據類型越來越豐富,這對數據處理的速度和能力提出了更高要求。Redis 是一種開源的內存非關係型數據庫,給開發人員帶來的體驗是顛覆性的。在自始至終的設計過程中,都充分考慮高性能,這使得 Redis 成為當今速度最快的 NoSQL 數據庫。

考慮高性能的同時,高可用也是很重要的考慮因素。互聯網 7x24 無間斷服務,在故障期間以最快的速度 Failover,能給企業帶來最小的損失。

那麼,在實際應用中,都有哪些高可用架構呢?架構之間有何優劣?我們應該怎麼取捨?有哪些最佳實踐?

二、Sentinel(哨兵)原理

在講解 Redis 高可用方案之前,我們先來看看 Redis Sentinel 原理(https://redis.io/topics/sentinel)是怎麼樣的。

  1. Sentinel 集群通過給定的配置文件發現 master,啟動時會監控 master。通過向 master 發送 info 信息獲得該服務器下面的所有從服務器。
  2. Sentinel 集群通過命令連接向被監視的主從服務器發送 hello 信息 (每秒一次),該信息包括 Sentinel 本身的 IP、端口、id 等內容,以此來向其他 Sentinel 宣告自己的存在。
  3. Sentinel 集群通過訂閱連接接收其他 Sentinel 發送的 hello 信息,以此來發現監視同一個主服務器的其他 Sentinel;集群之間會互相創建命令連接用於通信,因為已經有主從服務器作為發送和接收 hello 信息的中介,Sentinel 之間不會創建訂閱連接。
  4. Sentinel 集群使用 ping 命令來檢測實例的狀態,如果在指定的時間內(down-after-milliseconds)沒有回覆或則返回錯誤的回覆,那麼該實例被判為下線。
  5. 當 failover 主備切換被觸發後,failover 並不會馬上進行,還需要 Sentinel 中的大多數 Sentinel 授權後才可以進行 failover,即進行 failover 的 Sentinel 會去獲得指定 quorum 個的 Sentinel 的授權,成功後進入 ODOWN 狀態。如在 5 個 Sentinel 中配置了 2 個 quorum,等到 2 個 Sentinel 認為 master 死了就執行 failover。
  6. Sentinel 向選為 master 的 slave 發送 SLAVEOF NO ONE 命令,選擇 slave 的條件是 Sentinel 首先會根據 slaves 的優先級來進行排序,優先級越小排名越靠前。如果優先級相同,則查看複製的下標,哪個從 master 接收的複製數據多,哪個就靠前。如果優先級和下標都相同,就選擇進程 ID 較小的。
  7. 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架構?技術大牛最全總結讓你一學就會!



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架構?技術大牛最全總結讓你一學就會!


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 端口

你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


部分業務只能通過外網訪問 Redis,上述兩種方案均不可用,於是衍生出了這種方案。Web 使用客戶端連接其中一臺 Redis Sentinel 集群中的一臺機器的某個端口,然後通過這個端口獲取到當前的主節點,然後再連接到真實的 Redis 主節點進行相應的業務員操作。需要注意的是,Redis Sentinel 端口和 Redis 主節點均需要開放訪問權限。如果前端業務使用 Java,有 JedisSentinelPool 可以複用;如果前端業務使用 PHP,可以在 phpredis 的基礎上做二次封裝。

優點:

  • 服務探測故障及時
  • DBA 維護成本低


缺點:

  • 依賴客戶端支持 Sentinel
  • Sentinel 服務器和 Redis 節點需要開放訪問權限
  • 對應用有侵入性


4、Redis Sentinel 集群 + Keepalived/Haproxy


你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


Redis Sentinel 集群 + Keepalived/Haproxy


底層是 Redis Sentinel 集群,代理著 Redis 主從,Web 端通過 VIP 提供服務。當主節點發生故障,比如機器故障、Redis 節點故障或者網絡不可達,Redis 之間的切換通過 Redis Sentinel 內部機制保障,VIP 切換通過 Keepalived 保障。

優點:

  • 秒級切換
  • 對應用透明


缺點:

  • 維護成本高
  • 存在腦裂
  • Sentinel 模式存在短時間的服務不可用


5、Redis M/S + Keepalived


你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


Redis M/S + Keepalived


此方案沒有使用到 Redis Sentinel。此方案使用了原生的主從和 Keepalived,VIP 切換通過 Keepalived 保障,Redis 主從之間的切換需要自定義腳本實現。

優點:

  • 秒級切換
  • 對應用透明
  • 部署簡單,維護成本低


缺點:

  • 需要腳本實現切換功能
  • 存在腦裂


6、Redis Cluster


你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


Redis Cluster


From: http://intro2libsys.com/focused-redis-topics/day-one/intro-redis-cluster

Redis 3.0.0 在 2015 年 4 月 2 日正式發佈,距今已有兩年多的時間。Redis 集群採用 P2P 模式,無中心化。把 key 分成 16384 個 slot,每個實例負責一部分 slot。客戶端請求對應的數據,若該實例 slot 沒有對應的數據,該實例會轉發給對應的實例。另外,Redis 集群通過 Gossip 協議同步節點信息。

優點:

  • 組件 all-in-box,部署簡單,節約機器資源
  • 性能比 proxy 模式好
  • 自動故障轉移、Slot 遷移中數據可用
  • 官方原生集群方案,更新與支持有保障


缺點:

  • 架構比較新,最佳實踐較少
  • 多鍵操作支持有限(驅動可以曲線救國)
  • 為了性能提升,客戶端需要緩存路由表信息
  • 節點發現、reshard 操作不夠自動化


7、Twemproxy


你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


Twemproxy


From: http://engineering.bloomreach.com/the-evolution-of-fault-tolerant-redis-cluster

多個同構 Twemproxy(配置相同)同時工作,接受客戶端的請求,根據 hash 算法,轉發給對應的 Redis。

Twemproxy 方案比較成熟了,之前我們團隊長期使用此方案,但是效果並不是很理想。一方面是定位問題比較困難,另一方面是它對自動剔除節點的支持不是很友好。

優點:

  • 開發簡單,對應用幾乎透明
  • 歷史悠久,方案成熟


缺點:

  • 代理影響性能
  • LVS 和 Twemproxy 會有節點性能瓶頸
  • Redis 擴容非常麻煩
  • Twitter 內部已放棄使用該方案,新使用的架構未開源


8、Codis


你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!


Codis


From: https://github.com/CodisLabs/codis

Codis 是由豌豆莢開源的產品,涉及組件眾多,其中 ZooKeeper 存放路由表和代理節點元數據、分發 Codis-Config 的命令;Codis-Config 是集成管理工具,有 Web 界面供使用;Codis-Proxy 是一個兼容 Redis 協議的無狀態代理;Codis-Redis 基於 Redis 2.8 版本二次開發,加入 slot 支持,方便遷移數據。

優點:

  • 開發簡單,對應用幾乎透明
  • 性能比 Twemproxy 好
  • 有圖形化界面,擴容容易,運維方便


缺點:

  • 代理依舊影響性能
  • 組件過多,需要很多機器資源
  • 修改了 Redis 代碼,導致和官方無法同步,新特性跟進緩慢
  • 開發團隊準備主推基於 Redis 改造的 reborndb

四、最佳實踐

所謂的最佳實踐,都是最適合具體場景的實踐。

主推以下方案:

  • Redis Sentinel 集群 + 內網 DNS + 自定義腳本
  • Redis Sentinel 集群 + VIP + 自定義腳本


以下是實戰過程中總結出的最佳實踐:

  • Redis Sentinel 集群建議使用 >= 5 臺機器
  • 不同的大業務可以使用一套 Redis Sentinel 集群,代理該業務下的所有端口
  • 根據不同的業務劃分好 Redis 端口範圍
  • 自定義腳本建議採用 Python 實現,擴展便利
  • 自定義腳本需要注意判斷當前的 Sentinel 角色
  • 自定義腳本傳入參數:<service> <role> <comment> <from> <from> /<from>/<from>/<comment>/<role>/<service>
  • 自定義腳本需要遠程 ssh 操作機器,建議使用 paramiko 庫,避免重複建立 SSH 連接,消耗時間
  • 加速 SSH 連接,建議關閉以下兩個參數
  • UseDNS no
  • GSSAPIAuthentication no
  • 微信或者郵件告警,建議 fork 一個進程,避免主進程阻塞
  • 自動切換和故障切換,所有操作建議在 15s 以內完成

今日福利,資源免費分享!你想要的,全都有~

redis 部分資源展示:

你還不會搭建高可用redis架構?技術大牛最全總結讓你一學就會!

獲取方式:關注黑馬程序員頭條號,評論轉發後臺回覆“Redis” 即可


分享到:


相關文章: