Redis高可用簡要梳理

Redis因為其高性能和易用性在我們後端的服務中發揮了巨大的作用,並且很多重要功能的實現都會依賴redis。除了常用的緩存,還有隊列,發布訂閱等重要用處。所以redis的服務高可用就顯得尤為關鍵。這裡從redis的高可用入手,梳理了一下目前主流的方案。

Redis-Sentinel

Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立運行的進程,它能監控多個master-slave集群,發現master宕機後能進行自動切換。

它的主要功能有以下幾點

  • 不時地監控redis是否按照預期良好地運行;
  • 如果發現某個redis節點運行出現狀況,能夠通知另外一個進程(例如它的客戶端);
  • 能夠進行自動切換。當一個master節點不可用時,能夠選舉出master的多個slave(如果有超過一個slave的話)中的一個來作為新的master,其它的slave節點會將它所追隨的master的地址改為被提升為master的slave的新地址。

Sentinel支持集群

很顯然,只使用單個sentinel進程來監控redis集群是不可靠的,當sentinel進程宕掉後(sentinel本身也有單點問題,single-point-of-failure)整個集群系統將無法按照預期的方式運行。所以有必要將sentinel集群,這樣有幾個好處:

  • 即使有一些sentinel進程宕掉了,依然可以進行redis集群的主備切換;
  • 如果只有一個sentinel進程,如果這個進程運行出錯,或者是網路堵塞,那麼將無法實現redis集群的主備切換(單點問題);
  • 如果有多個sentinel,redis的客戶端可以隨意地連接任意一個sentinel來獲得關於redis集群中的信息。

redis-sentinel方案提供了單點的高可用解決方案,但是當數據量和業務量極速增長時,單點的reids不可能無限的縱向擴容(增大內存), 這個時候就需要redis有集群的能力來扛。 redis集群的幾種實現方式如下:

  • 客戶端分片

    優點簡單客戶端sharding不支持動態增刪節點。劣勢很大服務端Redis實例群拓撲結構有變化時,每個客戶端都需要更新調整。連接不能共享,當應用規模增大時,資源浪費制約優化。一般不採用。
  • 基於代理的分片,如codis和Twemproxy
  • 路由查詢, redis-cluster

Twemproxy

Twemproxy也叫nutcraker,是twtter開源的一個redis和memcache代理伺服器程序。redis作為一個高效的緩存伺服器,非常具有應用價值。但在用戶數據量增大時,需要運行多個redis實例,此時將迫切需要一種工具統一管理多個redis實例,避免在每個客戶端管理所有連接帶來的不方便和不易維護,Twemproxy即為此目標而生。

主要工作方式

分散式邏輯和存儲引擎分開,邏輯層proxy代理,存儲用的是原子redis,當每個層面需要添加刪除節點必須重啟服務生效(要重新利用散列函數生成KEY分片更新)

Proxy無狀態,redis數據層有狀態的,客戶端可以請求任一proxy代理上面,再由其轉發至正確的redis節點,該KEY分片演算法至某個節點都是預先已經算好的,在proxy配置文件保存著,但是如果更新或者刪除節點,又要根據一致性hash重新計算分片,並且重啟服務。

一致性hash演算法,增減節點需要配置proxy通知新的演算法,重啟服務

優點:

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

缺點:

  • 代理影響性能
  • 無法平滑地擴容/縮容
  • 運維比較困難
  • proxy單點本身會有性能瓶頸

Codis

codis由3大組件構成:

  • codis-server : 修改過源碼的redis, 支持slot,擴容遷移等
  • codis-proxy : 支持多線程,go語言實現的內核
  • codis Dashboard : 集群管理工具 提供web圖形界面管理集群。 集群元數據存在在zookeeper或etcd。(Zookeeper/etcd存放數據路由表和codis-proxy節點的元信息,codis-config發起的命令通過其同步到各個存活的codis-proxy) 提供獨立的組件codis-ha負責redis節點主備切換。 基於proxy的codis,客戶端對路由表變化無感知。客戶端需要從codis dashhoard調用list proxy命令獲取所有proxy列表,並根據自身的輪詢策略決定訪問哪個proxy節點以實現負載均衡。

    整個集群分為1024個哈希槽,分片演算法位SlotId = crc32(key) % 1024,增減節點不需要重啟服務

主要工作方式

分散式邏輯和存儲引擎分開,邏輯層codis-proxy,存儲用的是修改過的codis-server,這種好處是proxy層可以自動擴展和收縮,存儲層也同樣可以,每個層面都可以熱插撥

proxy無狀態,codis-server分為組間,每個組存在一個主節點(必須有並且只能有一個)和多個從節點。客戶端請求都是和proxy鏈接,鏈接哪個proxy都一樣,然後由它根據zookeeper路由信息轉發至正確節點,直接可以定位到正確節點上

優點:

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

缺點:

  • 代理影響性能
  • 組件過多,需要很多機器資源,部署比較難
  • 修改了 Redis 代碼,導致和官方無法同步,新特性跟進緩慢

Redis Cluster

主要工作方式

分散式的邏輯和存儲引擎不分開,即又負責讀寫操作,又負責集群交互,升級困難,如果代碼有bug,集群無法工作 這個結構為無中心的組織,不好把控集群當前的存活狀態,客戶端可以向任一節點發送請求,再有其重定向正確的節點上。如果在第一次請求和重定向期間cluster拓撲結構改變,則需要再一次或者多次重定向至正確的節點,但是這方面性能可以忽悠不計

整個集群分為16384個哈希槽,分片演算法位SlotId = crc16(key) % 16384,增減節點不需要重啟服務。Redis 集群通過 Gossip 協議同步節點信息,基本思想是節點之間互相交換信息最終所有節點達到一致。BTW. redis sentinel集群判定redis主節點down掉也是採用gossip協議。關於Gossip參考wiki。

優點:

  • 組件 all-in-box,部署簡單
  • 性能最快(沒有proxy)
  • 自動故障轉移、Slot 遷移中數據可用
  • 官方原生集群方案,更新與支持有保障

缺點:

  • 實踐不多
  • 客戶端開放成本高(客戶端不夠成熟)
  • 多鍵操作支持有限
  • reshard 操作不夠自動化(redis-trib.rb )

@lxkaka

本文版權屬於再惠研發團隊,歡迎轉載,轉載請保留出處。

推薦閱讀:

redis的setbit這個bit怎麼理解,配合bitcount使用?
200G的數據,主要是查詢操作,酷睿I5個人PC,應該選擇什麼資料庫來存儲?
Redis 哈希槽的概念,到底是什麼?是一個表的表名就會佔用一個哈希槽?
Redis從入門到入門(一)--Redis簡介及搭建
Redis Cluster 原理與管理

TAG:後端技術 | Redis |