Redis Cluster與Codis的選擇

Redis Cluster與Codis的選擇

一、Codis

1.1 Codis是什麼

Codis 是 Wandoujia Infrastructure Team 開發的一個分佈式 Redis 服務, 用戶可以看成是一個無限內存的 Redis 服務, 有動態擴/縮容的能力. 對偏存儲型的業務更實用, 如果你需要 SUBPUB 之類的指令, Codis 是不支持的. 時刻記住 Codis 是一個分佈式存儲的項目. 對於海量的 key, value不太大( <= 1M ), 隨着業務擴展緩存也要隨之擴展的業務場景有特效。

1.2 Codis的優勢

Redis獲得動態擴容/縮容的能力,增減redis實例對client完全透明、不需要重啓服務,不需要業務方擔心 Redis 內存爆掉的問題. 也不用擔心申請太大, 造成浪費. 業務方也不需要自己維護 Redis.

Codis支持水平擴容/縮容,擴容可以直接界面的 “Auto Rebalance” 按鈕,縮容只需要將要下線的實例擁有的slot遷移到其它實例,然後在界面上刪除下線的group即可。

1.3 Codis的組件

Codis 3.x 由以下組件組成:

  • Codis Server:基於 redis-3.2.8 分支開發。增加了額外的數據結構,以支持 slot 有關的操作以及數據遷移指令。
  • Codis Proxy:客戶端連接的 Redis 代理服務, 實現了 Redis 協議。 除部分命令不支持以外,表現的和原生的 Redis 沒有區別(就像 Twemproxy)。
    • 對於同一個業務集羣而言,可以同時部署多個 codis-proxy 實例;
    • 不同 codis-proxy 之間由 codis-dashboard 保證狀態同步。
  • Codis Dashboard:集羣管理工具,支持 codis-proxy、codis-server 的添加、刪除,以及據遷移等操作。在集羣狀態發生改變時,codis-dashboard 維護集羣下所有 codis-proxy 的狀態的一致性。
    • 對於同一個業務集羣而言,同一個時刻 codis-dashboard 只能有 0個或者1個;
    • 所有對集羣的修改都必須通過 codis-dashboard 完成。
  • Codis Admin:集羣管理的命令行工具。
    • 可用於控制 codis-proxy、codis-dashboard 狀態以及訪問外部存儲。
  • Codis FE:集羣管理界面。
    • 多個集羣實例共享可以共享同一個前端展示頁面;
    • 通過配置文件管理後端 codis-dashboard 列表,配置文件可自動更新。
  • Storage:爲集羣狀態提供外部存儲。
    • 提供 Namespace 概念,不同集羣的會按照不同 product name 進行組織;
    • 目前僅提供了 Zookeeper、Etcd、Fs 三種實現,但是提供了抽象的 interface 可自行擴展。

1.4 Codis是如何分片的?

Codis 採用 Pre-sharding 的技術來實現數據的分片, 默認分成 1024 個 slots (0-1023), 對於每個key來說, 通過以下公式確定所屬的 Slot Id : SlotId = crc32(key) % 1024。

每一個 slot 都會有一個且必須有一個特定的 server group id 來表示這個 slot 的數據由哪個 server group 來提供。數據的遷移也是以slot爲單位的。

二、Redis Cluster

redis cluster 是redis官方提供的分佈式解決方案,在3.0版本後推出的,有效地解決了redis分佈式的需求,當一個redis節點掛了可以快速的切換到另一個節點。當遇到單機內存、併發等瓶頸時,可以採用分佈式方案要解決問題。

2.1 redis集羣數據分片

以下內容翻譯自redis官網文檔:


Cluster不使用一致的哈希,而是使用一種不同形式的分片,其中每個鍵從概念上講都是我們稱爲哈希槽的一部分

Redis集羣中有16384個哈希槽,要計算給定密鑰的哈希槽,我們只需對密鑰的CRC16取模16384。

Redis羣集中的每個節點都負責哈希槽的子集,因此,例如,您可能有一個包含3個節點的羣集,其中:

  • 節點A包含從0到5500的哈希槽。
  • 節點B包含從5501到11000的哈希槽。
  • 節點C包含從11001到16383的哈希槽。

這樣可以輕鬆添加和刪除集羣中的節點。例如,如果我想添加一個新節點D,則需要將一些哈希槽從節點A,B,C移到D。類似地,如果我想從羣集中刪除節點A,則只需移動A所服務的哈希槽到B和C。當節點A爲空時,我可以將其從羣集中完全刪除。

因爲將哈希槽從一個節點移動到另一個節點不需要停止操作,所以添加和刪除節點或更改節點持有的哈希槽的百分比不需要任何停機時間。

2.2 redis集羣的主從模型(高可用)

  1. 一個集羣裏面有M1、M2、M3三個節點,其中節點 M1包含 0 到 5500號哈希槽,節點M2包含5501 到 11000 號哈希槽,節點M3包含11001 到 16384號哈希槽。如果M2宕掉了,就會導致5501 到 11000 號哈希槽不可用,從而使整個集羣不可用。
  2. 一個集羣裏面有M1-S1、M2-S2、M3-S3六個主從節點,其中節點 M1包含 0 到 5500號哈希槽,節點M2包含5501 到 11000 號哈希槽,節點M3包含11001 到 16384號哈希槽。如果是M2宕掉,集羣便會選舉S2爲新節點繼續服務,整個集羣還會正常運行。當M2、S2都宕掉了,這時候集羣就不可用了。

redis集羣至少需要一個備份節點,才能更好的保證集羣的高可用。

2.3 集羣的一致性保證

Redis Cluster無法保證強一致性。實際上,這意味着在某些情況下,Redis Cluster可能會丟失系統認可給客戶端的寫入。Redis Cluster可能丟失寫入的第一個原因是因爲它使用異步複製

可能的異常情況:

  1. 您的客戶寫信給主B。
  2. 主B向您的客戶答覆“確定”。
  3. 主機B將寫操作傳播到其從機B1,B2和B3。

B在回覆客戶端之前不會等待B1,B2,B3的確認,因爲這會對Redis造成延遲性的延遲,因此,如果您的客戶端寫了一些東西,B會確認寫,但是在崩潰之前崩潰由於能夠將寫操作發送到其從屬服務器,因此一個從屬服務器(未接收到寫操作)可以升級爲主服務器,從而永遠丟失該寫操作。

2.4 關於集羣的一些配置

  • cluster-enabled<yes/no>:如果yes,則在特定的Redis實例中啓用Redis Cluster支持。否則,該實例將像往常一樣作爲獨立實例啓動。
  • cluster-config-file:請注意,儘管有此選項的名稱,但它不是用戶可編輯的配置文件,而是Redis Cluster節點每次發生更改時都會自動持久保存集羣配置的文件(狀態,基本上是狀態),爲了能夠在啓動時重新閱讀它。該文件列出了諸如羣集中其他節點之類的內容,它們的狀態,持久變量等等。通常,由於收到某些消息,此文件將被重寫並刷新到磁盤上。
  • cluster-node-timeout:Redis羣集節點不可用的最長時間(不將其視爲失敗)。如果主節點無法訪問的時間超過指定的時間長度,則它的從節點將對其進行故障轉移。此參數控制Redis Cluster中的其他重要事項。值得注意的是,在指定的時間內無法到達大多數主節點的每個節點都將停止接受查詢。
  • cluster-slave-validity-factor:如果設置爲零,則從服務器將始終嘗試對主服務器進行故障轉移,而不管主服務器和從服務器之間的鏈接保持斷開狀態的時間長短。如果該值爲正,則將最大斷開時間計算爲節點超時值乘以此選項提供的係數,如果節點是從節點,則如果斷開主鏈接的時間超過指定的時間,它將不會嘗試啓動故障轉移。例如,如果節點超時設置爲5秒,而有效性因子設置爲10,則從服務器與主服務器斷開連接超過50秒將不會嘗試對其主服務器進行故障轉移。請注意,如果沒有從屬能夠對其進行故障轉移,則任何非零的值都可能導致Redis羣集在主服務器發生故障後不可用。在這種情況下,只有當原始主服務器重新加入集羣后,集羣纔會返回可用狀態。
  • cluster-migration-barrier:一個主機將保持連接的最小數量的從機,以便另一個從機遷移到不再被任何從機覆蓋的主機。有關更多信息,請參見本教程中有關副本遷移的相應部分。
  • cluster-require-full-coverage<yes/no>:如果設置爲yes,默認情況下,如果某個節點未覆蓋一定比例的密鑰空間,集羣將停止接受寫入。如果該選項設置爲no,即使僅可以處理有關密鑰子集的請求,羣集仍將提供查詢。

三、關於Codis與Redis Cluster的比較

Codis Redis Cluster
數據庫數量 16 1
Redis版本 3.2.8分支開發 5.0.6
不支持的命令 KEYS等 跨節點multi-key命令
可視化客戶端
集羣結構 代理
類中心化結構
集羣管理層與存儲層
解耦
P2P模型
Gossip協議
去中心化
哈希槽 1024 16384
主從複製 不負責 負責
升級 後續升級無法保證 Redis官方推出,後續升級可保證
事務支持 不支持 支持

選擇Redis Cluster的場景:

  1. 需要redis的新特性,例如:Stream
  2. 需要更豐富的命令支持
  3. 資源緊張

選擇Codis的場景:

  1. Codis支持的命令可滿足需求
  2. 資源充裕
  3. 強調可靠性

考慮到我們公司的需求,採用Redis cluster集羣搭建,採用redis Stream來提升性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章