Redis為什麼快及其高可用技術的幾種方案

lightTrace發表於2018-08-29

一 redis為什麼快?
redis近幾年快速發展,作為一種成熟的快取方案在各個大大小小的專案中使用
據官方測試redis可以達到10萬+的qps,這個次數不比使用單程式多執行緒的Memcached差!那為什麼這麼快呢?
我也使用redis很久了,知道redis快的原因大概兩點:記憶體直接讀寫減少磁碟io;單執行緒多路非阻塞io減少執行緒切換上下文的時間。
官方說法:
1、完全基於記憶體,絕大部分請求是純粹的記憶體操作,非常快速。資料存在記憶體中,類似於HashMap,HashMap的優勢就是查詢和操作的時間複雜度都是O(1);

2、資料結構簡單,對資料操作也簡單,Redis中的資料結構是專門進行設計的;

3、採用單執行緒,避免了不必要的上下文切換和競爭條件,也不存在多程式或者多執行緒導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的效能消耗;

4、使用多路I/O複用模型,非阻塞IO;

5、使用底層模型不同,它們之間底層實現方式以及與客戶端之間通訊的應用協議不一樣,Redis直接自己構建了VM 機制 ,因為一般的系統呼叫系統函式的話,會浪費一定的時間去移動和請求;

二 幾種方案的優缺點
redis提供了層次遞進的技術方案,無論是剛創業的小而美的公司又或者是大而全的巨無霸都可以從其中找到合適的解決方案,當然,這對我們的redis開發人員就提出了更高的要求,如何避免過多設計和資源的合理分配是一個很重要的問題。
那麼redis有哪幾種快取解決方案呢?
Redis 單副本
Redis 多副本(主從)
Redis Sentinel(哨兵)
Redis Cluster

當然我們還可以基於redis進行二次研發,這裡不做討論。方案很多,並不是越高大上的叢集高可用就越好,我們要根據公司自身的業務來合理的選擇方案來達到資源的合理化,既能減少資源的使用也能減少開發運維人員的工作量,總之一句話:“適合自己的才是最好的!”
所以我們應當瞭解redis幾種方案的優劣及適用場景:

1 Redis單副本

redis單副本,採用單個redis節點部署,沒有備用節點實時同步資料,不提供資料的持久化和備份策略,適用於資料可靠性要求不高的純快取業務場景
優點:

  • 架構簡單,部署方便
  • 高價效比,快取使用無需備用節點,當然為了滿足業務的高可用性,也可以犧牲一個備用節點,但同一時刻只有一個例項對外提供服務
  • 高效能

缺點:

  • 沒有持久化策略,自然不保證資料的可靠性
  • 在快取使用,程式重啟後資料丟失,即使有備用的節點解決 高可用性,但是仍然不能解決快取預熱問題,因此不適用於資料可靠性要求高的業務

  • 高效能受限於單核cpu的處理能力(因為redis是單執行緒機制)

    2 Redis 多副本(主從)

redis多副本,採用主從部署結構,相較於單副本而言最大的特點是主從例項間資料實時同步,並提供資料持久化和備份策略
主從例項部署在不同的物理伺服器上,根據公司的基礎環境配置,可以同時對外提供服務和讀寫分離策略

優點:

  • 高可靠性:一方面採用雙機主備架構,能夠在主庫出現故障時自動進行主備切換,從庫提升為主庫服務,保證服務平穩執行;另一方面開啟資料持久化功能和配置合理的備份策略,能有效的解決資料誤操作和資料異常丟失的問題
  • 讀寫分離策略:從節點可以擴充套件主庫節點的能力,有效應對大併發量的讀操作

缺點:

  • 故障恢復複雜,如果沒有Redis
    HA系統,當主庫節點出現故障,需手動升級一個節點為主節點,同時通知業務變更配置,並且需要讓其他從庫節點去複製新主庫節點,整個過程人為干預比較繁瑣

  • 主庫的寫能力收到單機限制,可以考慮分片

  • 主庫的儲存能力受到單機的限制,可以考慮pika

    Redis Sentinel(哨兵)

    Redis Sentinel是社群推出的原生高可用解決方案,其部署架構主要包括兩部分:Redis Sentinel叢集和Redis資料叢集
    其中哨兵叢集是由於若干Sentinel節點組成的分散式叢集,可以實現故障發現、故障自動轉移、配置中心和客戶端通知。哨兵的節點數量要滿足2n+1的奇數個

    優點:

  • Redis Sentinel叢集部署簡單

  • 能夠解決Redis主從模式下的高可用切換問題

  • 很方便實現redis資料節點的線性擴充套件,輕鬆突破redis自身單執行緒瓶頸,可極大滿足redis大容量或高效能的業務需求

  • 可以實現一套Redis sentinel監控一組redis資料節點或多組資料節點

    缺點:

  • 部署相對主從更復雜一些

  • 資源浪費,Redis資料節點中slave節點作為備份節點不提供服務

  • Redis Sentinel 主要是針對 Redis 資料節點中的主節點的高可用切換,對 Redis
    的資料節點做失敗判定分為主觀下線和客觀下線兩種,對於 Redis 的從節點有對節點做主觀下線操作,並不執行故障轉移。

  • 不能解決讀寫分離問題,實現起來相對複雜。
    4 Redis Cluster

Redis Cluster是社群版推出的Redis分散式叢集解決方案,主要解決Redis分散式方面的需求,比如單機記憶體併發和流量瓶頸的時候,Redis Cluster能起到很好的負載均衡的目的

Redis Cluster叢集節點最小配置6個及以上節點(3主3從),其中主節點提供讀寫操作,從節點作為備用節點不提供請求,只為故障轉移使用。
Redis Cluster採用虛擬槽分割槽,所有的鍵根據雜湊函式對映到0~16383個整數槽內,每個節點負責維護一部分以及所對映的鍵值資料

優點:

  • 無中心架構
  • 資料按照slot儲存分佈在多個節點,節點間資料共享,可以動態調整資料分佈;
  • 可擴充套件性:可線性擴充套件到1000多個節點,節點可以動態新增或者刪除
  • 高可用性:部分節點不可用時,叢集仍可用。通過增加slave做standby資料副本

  • 能夠實現故障自動failover,節點之間通過gossip協議交換狀態資訊,用投票機制完成slave到master的提升

  • 降低運維成本,提高系統的可擴充套件性和可用性

    缺點:

  • Client 實現複雜,驅動要求實現 Smart Client,快取 slots mapping
    資訊並及時更新,提高了開發難度,客戶端的不成熟影響業務的穩定性。目前僅 JedisCluster
    相對成熟,異常處理部分還不完善,比如常見的“max redirect exception”。

  • 節點會因為某些原因發生阻塞(阻塞時間大於 clutser-node-timeout),被判斷下線,這種 failover 是沒有必要的。

  • 資料通過非同步複製,不保證資料的強一致性。

  • 多個業務使用同一套叢集時,無法根據統計區分冷熱資料,資源隔離性較差,容易出現相互影響的情況。

  • Slave 在叢集中充當“冷備”,不能緩解讀壓力,當然可以通過 SDK 的合理設計來提高 Slave 資源的利用率。

  • Key 批量操作限制,如使用 mset、mget 目前只支援具有相同 slot 值的 Key 執行批量操作。對於對映為不同 slot 值的
    Key 由於 Keys 不支援跨 slot 查詢,所以執行 mset、mget、sunion 等操作支援不友好。

  • Key 事務操作支援有限,只支援多 key 在同一節點上的事務操作,當多個 Key 分佈於不同的節點上時無法使用事務功能。

  • Key 作為資料分割槽的最小粒度,不能將一個很大的鍵值物件如 hash、list 等對映到不同的節點。

  • 不支援多資料庫空間,單機下的 redis 可以支援到 16 個資料庫,叢集模式下只能使用 1 個資料庫空間,即db 0 。

  • 複製結構只支援一層,從節點只能複製主節點,不支援巢狀樹狀複製結構。
  • 避免產生 hot-key,導致主庫節點成為系統的短板。
  • 避免產生 big-key,導致網路卡撐爆、慢查詢等。
  • 重試時間應該大於 cluster-node-time 時間。

  • Redis Cluster 不建議使用 pipeline和multi-keys 操作,減少 max redirect 產生的場景。

相關文章