日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis集群解决方案比较

發布時間:2025/4/5 数据库 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis集群解决方案比较 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

調研比較了三個Redis集群的解決方案:

系統貢獻者是否官方Redis實現編程語言
TwemproxyTwitterC
Redis ClusterRedis官方C
Codis豌豆莢Go+C



1.基本架構
1.1 Twemproxy

  • 增加Proxy層,由Proxy實現一致性哈希算法(支持:KETAMA/取模/隨機)



數據分片算法:
采用一致性哈希算法,以KETAMA為例:


1.2 Redis Cluster

  • 無中心自組織的結構

  • 各節點維護Key->Server的映射關系

  • Client可以向任意節點發起請求,節點不會轉發請求,只是重定向Client

  • 如果在Client第一次請求和重定向請求之間,Cluster拓撲發生改變,則第二次重定向請求將被再次重定向,直到找到正確的Server為止


數據分片算法:
Key空間被劃分為16384個區間,每個Master節點負責一部分區間。

1.3 Codis

  • 客戶端可以連接到任意的codis-proxy,就和連接原生的Redis Server

  • 由Zookeeper維護數據路由表和 codis-proxy 節點的元信息


數據分片算法:

  • Key空間被劃分為1024個區間, 對于每個key來說, 通過以下公式確定所屬的 Slot Id : SlotId = crc32(key) % 1024

  • 每一個 slot 都會有一個特定的 server group id 來表示這個 slot 的數據由哪個 server group 來提供


2.水平擴容
Twemproxy:

  • 不支持運行時水平擴容,需要重啟。

  • 根據一致性哈希算法進行數據重新分片。


Redis Cluster:

  • 支持通過運行時增加Master節點來水平擴容,提升存儲容量,盡力降低命中率波動

  • 存在節點A,需要遷出其中的部分Key區間。新增節點B,接收由節點A遷出的Key區間。

  • 相應Key區間的請求首先還是會發送給A節點:如果請求為新建Key則直接重定向到B節點;如果請求不是新建Key且A節點存儲有對應的Key則直接作出響應,否則重定向到B節點

  • 同時Cluster會調用實用工具redis-trib向A節點發送MIGRATE命令,把遷移區間內的所有Key原子的遷移到B節點:同時鎖住A、B節點=》在A節點刪除Key=》在B節點新建Key=》解鎖

  • 運行時動態遷移大尺寸鍵值可能造成響應時延



Codis:

  • 支持運行時水平擴容

  • 底層基于Codis Server特殊實現原子的數據遷移指令




3.主從備份
3.1 主從備份是否必須
Twemproxy:

  • 沒有數據復制不影響可用節點頂替故障節點

  • 故障發生時,沒有數據復制的故障節點的Key會全部丟失


Redis Cluster:
沒有主從備份的節點一旦故障,將導致整個集群失敗:無法寫入/讀取任何Key;無法進行數據重新分片。

Codis:

  • 若出現故障,需要手動配置節點,進行故障轉移。

  • 如果沒有進行故障轉移,只故障節點負責的slots 會失敗



3.2 主從備份方案
Twemproxy本身不支持出從備份,和Redis Cluster一樣,需要引入Redis本身的主備復制功能。

  • 可以設置1主1備或者1主多備

  • 當Slave節點接入Cluster時,就會向配置的Master節點發送SYNC命令。斷開重連時,也會再次發送SYNC命令

  • 此后Master將啟動后臺存盤進程,同時收集所有接收到的用于修改數據集的命令,在后臺進程執行完畢后,Master將傳送整個數據 庫文件到Slave,以完成一次完全同步。而Slave服務器在接收到數據庫文件數據之后將其存盤并加載到內存中。此后,Master繼續將所有已經收集 到的修改命令,和新的修改命令依次傳送給Slaves,Slave將在本次執行這些數據修改命令,從而達到最終的數據同步。

  • Redis的數據復制是異步的,無論在Master端還是Slave端都不會阻塞。

  • Slave會周期性確認收到的備份數據




Twemproxy引入主備復制后的架構更新為:


開啟主備復制后的Redis Cluster的架構更新為下圖,Client可以向任意節點發起請求,無論是Master節點還是Slave節點。



4.故障檢測與轉移
4.1 Twemproxy
4.1.1 故障檢測
Twemproxy本身通過三個配置項實現:

Txt代碼 ?

  • auto_eject_hosts:?true??

  • timeout:?400??

  • server_failure_limit:?3??


  • 如果Server Pool開啟了auto_eject_hosts,則當連續server_failure_limit次訪問某Server,都超時timeout無響應,則標記該節點為故障。

    4.1.2 故障轉移
    故障節點將從Hash環上直接取下,之前保存在該Server上的Key將丟失。

    4.1.3 故障轉移耗時評估
    假設配置:timeout=400ms, server_failure_limit=2, 則故障轉移需要耗時800ms。


    4.2 Twemproxy借助其他工具
    使用Twemproxy時可以引入Redis Sentinel來進行故障檢測。引入Redis Sentinel后Twemproxy的架構更新為:

    • 每個Sentinel節點可以監控一個或多個Master節點,及其所有Slave節點



    4.2.1 啟動Redis Sentinel

    • redis-sentinel /path/to/sentinel.conf,其中的配置文件是必須的,配置文件將會被用來存儲運行時狀態信息。在配置文件中只需要指明要監視的Master節點列表。

    • 無須為運行的每個 Sentinel 分別設監聽同一Master的其他 Sentinel 的地址, 因為 Sentinel 可以通過發布與訂閱功能來自動發現正在監視相同主服務器的其他 Sentinel

    • 不必手動列出主服務器屬下的所有從服務器, 因為 Sentinel 可以通過詢問主服務器來獲得所有從服務器的信息。


    4.2.2 故障檢測

    • 每個 Sentinel 以每秒鐘一次的頻率向它所知的主服務器、從服務器以及其他 Sentinel 實例發送一個 PING 命令。

    • 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 那么這個實例會被 Sentinel 標記為主觀下線。

    • 如果一個Master被標記為主觀下線, 那么正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態。

    • 如果一個主服務器被標記為主觀下線, 并且有足夠數量的 Sentinel (至少要達到配置文件指定的數量)在指定的時間范圍內同意這一判斷, 那么這個主服務器被標記為客觀下線。

    • 當沒有足夠數量的 Sentinel 同意主服務器已經下線, 主服務器的客觀下線狀態就會被移除。 當主服務器重新向 Sentinel 的 PING 命令返回有效回復時, 主服務器的主觀下線狀態就會被移除。


    4.2.3 故障轉移
    Redis Sentinel進行故障轉移的過程:

    • 某Sentinel節點發現主服務器已經進入客觀下線狀態。

    • 該Sentinel發起選舉,試圖當選故障轉移主持節點

    • 如果當選失敗, 那么在設定的故障遷移超時時間的兩倍之后, 重新嘗試當選。 如果當選成功, 那么執行以下步驟。

    • 選出一個Slave節點,并將它升級為Master節點

    • 向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變為Master節點

    • 通過發布與訂閱功能, 將更新后的配置傳播給所有其他 Sentinel , 其他 Sentinel 對它們自己的配置進行更新。

    • 向已下線主服務器的Slave節點發送 SLAVEOF 命令, 讓它們去復制新的Master節點


    Redis Sentinel選擇新的Master節點進行故障轉移之后,Twemproxy無法找到新的Master節點,此時需要引入第四方工具redis-twemproxy-agent(node.js),更新Twemproxy配置,并重啟。


    4.2.4 故障轉移耗時評估

    • 每個 Sentinel 以每秒鐘發送一次PING,配置down-after-milliseconds=2s,則主觀下線耗時3s

    • 由主觀下線升:數量的 Sentinel (至少要達到配置文件指定的數量)在指定的時間范圍內同意這一判斷1s

    • Sentinel當選故障轉移主持節點:1s

    • 選出一個Slave節點,并將它升級為Master節點,向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變為Master節點:0.5s

    • 通過發布與訂閱功能, 將更新后的配置傳播給所有其他 Sentinel , 其他 Sentinel 對它們自己的配置進行更新:1s

    • 總計耗時:6.5s




    4.3 Redis Cluster
    4.3.1 故障檢測
    節點狀態的維護:

    • 節點的拓撲結構是一張完全圖:對于N個節點的Cluster,每個節點都持有N-1個輸入TCP連接和N-1個輸出TCP連接。

    • 節點信息的維護:每秒隨機選擇節點發送PING包(無論Cluster規模,PING包規模是常量);每個節點保證在NODE_TIMEOUT/2 時間內,對于每個節點都至少發送一個PING包或者收到一個PONG包.



    在節點間相互交換的PING/PONG包中有兩個字段用來發現故障節點:PFAIL(Possible Fail)和FAIL。

    PFAIL狀態:

    • 當一個節點發現某一節點在長達NODE_TIMEOUT的時間內都無法訪問時,將其標記為PFAIL狀態。

    • 任意節點都可以將其他節點標記為PFAIL狀態,無論它是Master節點還是Slave節點。



    FAIL狀態:
    當一個節點發現另一節點被自己標記為PFAIL狀態,并且在(NODE_TIMEOUT * FAIL_REPORT_VALIDITY_MULT)的時間范圍內,與其他節點交換的PING/PONG包中,大部分Master節點都把該節點標記為 PFAIL或者FAIL狀態,則把該節點標記為FAIL狀態,并且進行廣播。

    4.3.2 故障轉移
    4.3.2.1 Slave選舉的時機
    當某一Slave節點發現它的Master節點處于FAIL狀態時,可以發起一次Slave選舉,試圖將自己晉升為Master。一個Master節點的所有Slave節點都可以發起選舉,但最終只有一個Slave節點會贏得選舉。Slave發起選舉的條件:

    • Slave的Master處于FAIL狀態

    • 該MASTER節點存儲的Key數量>0

    • Slave與Master節點失去連接的時間小于閥值,以保證參與選舉的Slave節點的數據的新鮮度



    4.3.2.2 Cluster邏輯時鐘
    Config epoch:
    每個Master節點啟動時都會為自己創建并維護configEpoch字段,設置初始值為0。Master會在自己的PING/PONG包中廣 播自己的configEpoch字段。Redis Cluster盡力保持各個Master節點的configEpoch字段取值都不同。算法:

    • 每當一個Master節點發現有別的Master節點的configEpoch字段與自己相同時

    • 并且自己的Node ID比對方小(字母順序)

    • 則把自己的currentEpoch+1


    Slave的PING/PONG包中也包含configEpoch字段,Slave的configEpoch字段取值是它的Master的configEpoch字段取值,由最后一次與Master交換PING/PONG包時取得。

    Cluster epoch:
    每一個節點啟動的時候都會創建currentEpoch字段,無論是Master節點還是Slave節點,并設置初始值為0。每當一個節點收到來 自其他節點的PING/PONG包時,若其他節點的currentEpoch字段大于當前節點的currentEpoch字段,則當前節點把自己的 currentEpoch字段設置為該新觀察到的currentEpoch值。

    4.3.2.3 Slave選舉的過程

    • Slave節點遞增自己的currentEpoch字段

    • 發送FAILOVER_AUTH_REQUEST數據包給每一個MASTER節點

    • 若MASTER節點投票晉升該SLAVE節點,則回復FAILOVER_AUTH_ACK。某個MASTER節點投過票之后,在NODE_TIMEOUT * 2時間內不能再給同一MASTER的SLAVE選舉投票。

    • 若Slave在MAX((2*NODE_TIMEOUT),2)的時間內獲得大多數MASTER節點的投票,則贏得選舉

    • 其間,所有currentEpoch小于選舉發起時取值的MASTER投票都會被丟棄

    • 若沒有任何Slave贏得選舉,選舉可以在MAX(NODE_TIMEOUT * 4,4)的時間后重新舉行



    4.3.2.4 Master節點投票邏輯

    • 請求選舉的Slave的Master必須處于FAIL狀態

    • Master節點維護lastVoteEpoch字段,每當MASTER給某個選舉請求投票時,更新lastVoteEpoch字段為請求的currentEpoch值

    • currentEpoch<lastVoteEpoch的選舉請求都不予投票

    • currentEpoch<MASTER currentEpoch字段的選舉請求都不予投票



    4.2.3.5 選舉優先權
    當Slave節點發現Master節點處于FAIL狀態時,不會立刻試圖進行選舉,而是會延遲一段時間,延遲時常用以下公式進行計算:

    Txt代碼 ?

  • DELAY?=?500?milliseconds?+?random?delay?between?0?and?500?milliseconds?+???SLAVE_RANK?*?1000?milliseconds??


  • 其中,SLAVE_RANK由Slave收到Master數據復制的更新程度來衡量。在發起選舉之前,Slave之間交換各自獲得Master數據復制的更新排名,最新更新的SLAVE_RANK = 0, 其次更新的SLAVE_RANK = 1,以此類推...

    4.2.3.6 故障轉移耗時評估

    • 假設配置NODE_TIMEOUT=2s,FAIL_REPORT_VALIDITY_MULT=3s

    • 標記Master為PFAIL狀態耗時NODE_TIMEOUT=2s

    • 升級PFAIL狀態為FAIL狀態,耗時:NODE_TIMEOUT * FAIL_REPORT_VALIDITY_MULT = 6s

    • 選舉前隨機延時期望:1s

    • 收集足夠多Master投票:MAX((2*NODE_TIMEOUT),2)=4s

    • 總計耗時約:13s



    4.3.3 主備平衡功能
    Redis Cluster能夠自動的遷移Slave節點,從Slave節點有冗余的Master節點到完全沒有Slave節點的Master節點。
    具體算法:

    • 首先定義Good Slave:對于某一節點來說,如果另一個Slave節點沒有處于FAIL狀態,則認為該Slave節點為Good Slave節點。

    • 當有Slave節點發現有Master節點沒有Good Slave時開始觸發主備平衡遷移。

    • 所有發現有主備平衡需求之后,擁有最多Good Slave節點的Master節點的所有Slave中,Node ID最小的Slave節點真正開始遷移。成為沒有沒有Good Slave Master新Master。

    • 可以配置cluster-migration-barrier參數,控制主備平衡遷移的時候,遷出Master最少需要擁有的Good Slave數



    4.4 Codis

    • 支持故障檢測并報警

    • codis-redis-group中的Slave節點無法自動提升為Master節點

    • 由管理員通過Web界面/命令行來手動操作





    5.功能限制
    Twemproxy:

    • 不支持多key操作

    • 不支持MULTI/EXEC

    • 不支持EVAL


    Redis Cluster:

    • 當Client連接到集群的主體部分時可能有少量的寫丟失,當Client連接到集群的小部分時可能有顯著的寫丟失

    • 復雜的多Key操作(Set求并/求交)不能跨節點操作,可以通過使用Hash Tag使相關Key強制哈希到同一Server,但是在數據重新分片期間,還是可能有時間不可用

    • 不支持MULTI/EXEC

    • Redis 3.0 正式版時間:2015年2月上旬


    Codis:
    不支持命令:KEYS, MOVE, OBJECT, RENAME, RENAMENX, SORT, SCAN, BITOP,MSETNX, BLPOP, BRPOP, BRPOPLPUSH, PSUBSCRIBE,PUBLISH, PUNSUBSCRIBE, SUBSCRIBE, UNSUBSCRIBE, DISCARD, EXEC, MULTI, UNWATCH, WATCH, SCRIPT EXISTS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD, AUTH, ECHO, SELECT, BGREWRITEAOF, BGSAVE, CLIENT KILL, CLIENT LIST, CONFIG GET, CONFIG SET, CONFIG RESETSTAT, DBSIZE, DEBUG OBJECT, DEBUG SEGFAULT, FLUSHALL, FLUSHDB, INFO, LASTSAVE, MONITOR, SAVE, SHUTDOWN, SLAVEOF, SLOWLOG, SYNC, TIME


    6. 性能
    Twemproxy:[來源:http://antirez.com/news/44]

    • 通常操作Proxy與直接操作Redis實例性能一樣

    • 最壞情況下有20%的性能下降



    Redis Cluster:[來源: http://redis.io/topics/cluster-spec]
    1000個節點內擁有線性的伸縮性:通常情況下與直接操作Redis實例性能相同。

    Codis:[來源:http://0xffff.me/blog/2014/11/11/codis-de-she-ji-yu-shi-xian-part-3/]

    • 相對于單Redis實例40%性能損失

    • 支持多核




    7. 總結
    Twemprosy:

    • 輕量級

    • 在Proxy層實現一致性哈希

    • 快速的故障節點移除

    • 可借助Sentinel和重啟工具降低故障節點移除時的Cache失配



    Redis Cluster:

    • 無中心自組織結構

    • 更強的功能:主備平衡

    • 故障轉移響應時間長

    • 暫時未達到正式版



    Codis:

    • 基于Zookeeper的Proxy高可用

    • 非官方Redis實現

    • 側重于動態水平擴容

    • 手動故障轉移


    本文轉自 msj0905 51CTO博客,原文鏈接:http://blog.51cto.com/sky66/1719189

    總結

    以上是生活随笔為你收集整理的Redis集群解决方案比较的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。