當前位置: 妍妍網 > 碼農

Redis 4種集群方案介紹+優缺點對比

2024-05-13碼農

在服務開發中,單機都會存在單點故障的問題,即服務部署在一台伺服器上,一旦伺服器宕機服務就不可用,所以為了讓服務高可用,分布式服務就出現了,將同一服務部署到多台機器上,即使其中幾台伺服器宕機,只要有一台伺服器可用服務就可用。

redis也是一樣,為了解決單機故障引入了主從模式,但主從模式存在一個問題:master節點故障後服務,需要人為的手動將slave節點切換成為maser節點後服務才恢復。redis為解決這一問題又引入了哨兵模式,哨兵模式能在master節點故障後能自動將salve節點提升成master節點,不需要人工幹預操作就能恢復服務可用。

但是主從模式、哨兵模式都沒有達到真正的數據sharding儲存,每個redis例項中儲存的都是全量數據,所以redis cluster就誕生了,實作了真正的數據分片儲存。但是由於redis cluster釋出得比較晚(2015年才釋出正式版 ),各大廠等不及了,陸陸續續開發了自己的redis數據分片集群模式,比如:Twemproxy、Codis等。

主從模式

redis單節點雖然有透過RDB和AOF持久化機制能將數據持久化到硬碟上,但數據是儲存在一台伺服器上的,如果伺服器出現硬碟故障等問題,會導致數據不可用,而且讀寫無法分離,讀寫都在同一台伺服器上,請求量大時會出現I/O瓶頸。

為了避免單點故障 和 讀寫不分離,Redis 提供了復制(replication)功能實作master資料庫中的數據更新後,會自動將更新的數據同步到其他slave資料庫上。

如上redis主從結構特點:一個master可以有多個salve節點;salve節點可以有slave節點,從節點是級聯結構。

主從模式優缺點

  • 優點: 主從結構具有讀寫分離,提高效率、數據備份,提供多個副本等優點。

  • 不足: 最大的不足就是主從模式不具備自動容錯和恢復功能,主節點故障,集群則無法進行工作,可用性比較低,從節點升主節點需要人工手動幹預。

  • 普通的主從模式,當主資料庫崩潰時,需要手動切換從資料庫成為主資料庫:

  • 在從資料庫中使用SLAVE NO ONE命令將從資料庫提升成主數據繼續服務。

  • 啟動之前崩潰的主資料庫,然後使用SLAVEOF命令將其設定成新的主資料庫的從資料庫,即可同步數據。

  • 哨兵模式

    第一種主從同步/復制的模式,當主伺服器宕機後,需要手動把一台從伺服器切換為主伺服器,這就需要人工幹預,費事費力,還會造成一段時間內服務不可用,這時候就需要哨兵模式登場了。

    哨兵模式是從Redis的2.6版本開始提供的,但是當時這個版本的模式是不穩定的,直到Redis的2.8版本以後,這個哨兵模式才穩定下來。

    哨兵模式核心還是主從復制,只不過在相對於主從模式在主節點宕機導致不可寫的情況下,多了一個競選機制:從所有的從節點競選出新的主節點。競選機制的實作,是依賴於在系統中啟動一個sentinel行程。

    如上圖,哨兵本身也有單點故障的問題,所以在一個一主多從的Redis系統中,可以使用多個哨兵進行監控,哨兵不僅會監控主資料庫和從資料庫,哨兵之間也會相互監控。每一個哨兵都是一個獨立的行程,作為行程,它會獨立執行。

    (1)哨兵模式的作用:

    監控所有伺服器是否正常執行:透過發送命令返回監控伺服器的執行狀態,處理監控主伺服器、從伺服器外,哨兵之間也相互監控。

    故障切換:當哨兵監測到master宕機,會自動將slave切換成master,然後透過釋出訂閱模式通知其他的從伺服器,修改配置檔,讓它們切換master。同時那台有問題的舊主也會變為新主的從,也就是說當舊的主即使恢復時,並不會恢復原來的主身份,而是作為新主的一個從。

    (2)哨兵實作原理

    哨兵在啟動行程時,會讀取配置檔的內容,透過如下的配置找出需要監控的主資料庫:

    sentinel monitor master-name ip port quorum
    #master-name是主資料庫的名字
    #ip和port 是當前主資料庫地址和埠號
    #quorum表示在執行故障切換操作前,需要多少哨兵節點同意。

    這裏之所以只需要連線主節點,是因為透過主節點的info命令,獲取從節點資訊,從而和從節點也建立連線,同時也能透過主節點的info資訊知道新增從節點的資訊。

    一個哨兵節點可以監控多個主節點,但是並不提倡這麽做,因為當哨兵節點崩潰時,同時有多個集群切換會發生故障。哨兵啟動後,會與主資料庫建立兩條連線。

  • 訂閱主資料庫_sentinel_:hello頻道以獲取同樣監控該資料庫的哨兵節點資訊

  • 定期向主資料庫發送info命令,獲取主資料庫本身的資訊。

  • 跟主資料庫建立連線後會定時執行以下三個操作:

  • (1)每隔10s向master和 slave發送info命令。作用是獲取當前資料庫資訊,比如發現新增從節點時,會建立連線,並加入到監控列表中,當主從資料庫的角色發生變化進行資訊更新。

  • (2)每隔2s向主數據裏和從資料庫的_sentinel_:hello頻道發送自己的資訊。作用是將自己的監控數據和哨兵分享。每個哨兵會訂閱資料庫的_sentinel:hello頻道,當其他哨兵收到訊息後,會判斷該哨兵是不是新的哨兵,如果是則將其加入哨兵列表,並建立連線。

  • (3)每隔1s向所有主從節點和所有哨兵節點發送ping命令,作用是監控節點是否存活。

  • (3)主觀下線和客觀下線

    哨兵節點發送ping命令時,當超過一定時間(down-after-millisecond)後,如果節點未回復,則哨兵認為主觀下線。主觀下線表示當前哨兵認為該節點已經下線,如果該節點為主資料庫,哨兵會進一步判斷是夠需要對其進行故障切換,這時候就要發送命令(SENTINEL is-master-down-by-addr)詢問其他哨兵節點是否認為該主節點是主觀下線,當達到指定數量(quorum)時,哨兵就會認為是客觀下線。

    當主節點客觀下線時就需要進行主從切換,主從切換的步驟為:

  • 選出領頭哨兵。

  • 領頭哨兵所有的slave選出優先級最高的從資料庫。優先級可以透過slave-priority選項設定。

  • 如果優先級相同,則從資料庫復制的命令偏移量越大(即復制同步數據越多,數據越新),越優先。

  • 如果以上條件都一樣,則選擇run ID較小的從資料庫。

  • 選出一個從資料庫後,哨兵發送slave no one命令升級為主資料庫,並行送slaveof命令將其他從節點的主資料庫設定為新的主資料庫。

    (4)哨兵模式優缺點

    1.優點

  • 哨兵模式是基於主從模式的,解決可主從模式中master故障不可以自動切換故障的問題。

  • 2.不足-問題

  • 是一種中心化的集群實作方案:始終只有一個Redis主機來接收和處理寫請求,寫操作受單機瓶頸影響。

  • 集群裏所有節點保存的都是全量數據,浪費記憶體空間,沒有真正實作分布式儲存。數據量過大時,主從同步嚴重影響master的效能。

  • Redis主機宕機後,哨兵模式正在投票選舉的情況之外,因為投票選舉結束之前,誰也不知道主機和從機是誰,此時Redis也會開啟保護機制,禁止寫操作,直到選舉出了新的Redis主機。

  • 主從模式或哨兵模式每個節點儲存的數據都是全量的數據,數據量過大時,就需要對儲存的數據進行分片後儲存到多個redis例項上。此時就要用到Redis Sharding技術。

    各大廠的Redis集群方案

    Redis在3.0版本前只支持單例項模式,雖然Redis的開發者Antirez早在部落格上就提出在Redis 3.0版本中加入集群的功能,但3.0版本等到2015年才釋出正式版。各大企業等不及了,在3.0版本還沒釋出前為了解決Redis的儲存瓶頸,紛紛推出了各自的Redis集群方案。這些方案的核心思想是把數據分片(sharding)儲存在多個Redis例項中,每一片就是一個Redis例項。

    (1)客戶端分片

    客戶端分片是把分片的邏輯放在Redis客戶端實作,(比如:jedis已支持Redis Sharding功能,即ShardedJedis),透過Redis客戶端預先定義好的路由規則(使用一致性哈希),把對Key的存取轉發到不同的Redis例項中,查詢數據時把返回結果匯集。這種方案的模式如圖所示。

    客戶端分片的優缺點:

    優點:客戶端sharding技術使用hash一致性演算法分片的好處是所有的邏輯都是可控的,不依賴於第三方分布式中介軟體。伺服端的Redis例項彼此獨立,相互無關聯,每個Redis例項像單伺服器一樣執行,非常容易線性擴充套件,系統的靈活性很強。開發人員清楚怎麽實作分片、路由的規則,不用擔心踩坑。

    1.一致性哈希演算法:

    是分布式系統中常用的演算法。比如,一個分布式的儲存系統,要將數據儲存到具體的節點上,如果采用普通的hash方法,將數據對映到具體的節點上,如mod(key,d),key是數據的key,d是機器節點數,如果有一個機器加入或結束這個集群,則所有的數據對映都無效了。

    一致性哈希演算法解決了普通余數Hash演算法伸縮性差的問題,可以保證在上線、下線伺服器的情況下盡量有多的請求命中原來路由到的伺服器。

    2.實作方式:一致性hash演算法,比如MURMUR_HASH雜湊演算法、ketamahash演算法

    比如Jedis的Redis Sharding實作,采用一致性哈希演算法(consistent hashing),將key和節點name同時hashing,然後進行對映匹配,采用的演算法是MURMUR_HASH。

    采用一致性哈希而不是采用簡單類似哈希求模對映的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性哈希只影響相鄰節點key分配,影響量小。

    不足:

  • 這是一種靜態的分片方案,需要增加或者減少Redis例項的數量,需要手工調整分片的程式。

  • 運維成本比較高,集群的數據出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。

  • 在不同的客戶端程式中,維護相同的路由分片邏輯成本巨大。比如:java計畫、PHP計畫裏共用一套Redis集群,路由分片邏輯分別需要寫兩套一樣的邏輯,以後維護也是兩套。

  • 客戶端分片有一個最大的問題就是,伺服端Redis例項群拓撲結構有變化時,每個客戶端都需要更新調整。如果能把客戶端分片模組單獨拎出來,形成一個單獨的模組(中介軟體),作為客戶端 和 伺服端連線的橋梁就能解決這個問題了,此時代理分片就出現了。

    (2)代理分片

    redis代理分片用得最多的就是Twemproxy,由Twitter開源的Redis代理,其基本原理是:透過中介軟體的形式,Redis客戶端把請求發送到Twemproxy,Twemproxy根據路由規則發送到正確的Redis例項,最後Twemproxy把結果匯集返回給客戶端。

    Twemproxy透過引入一個代理層,將多個Redis例項進行統一管理,使Redis客戶端只需要在Twemproxy上進行操作,而不需要關心後面有多少個Redis例項,從而實作了Redis集群。

    Twemproxy的優點:

  • 客戶端像連線Redis例項一樣連線Twemproxy,不需要改任何的程式碼邏輯。

  • 支持無效Redis例項的自動刪除。

  • Twemproxy與Redis例項保持連線,減少了客戶端與Redis例項的連線數。

  • Twemproxy的不足:

  • 由於Redis客戶端的每個請求都經過Twemproxy代理才能到達Redis伺服器,這個過程中會產生效能損失。

  • 沒有友好的監控管理後台界面,不利於運維監控。

  • Twemproxy最大的痛點在於,無法平滑地擴容/縮容。對於運維人員來說,當因為業務需要增加Redis例項時工作量非常大。

  • Twemproxy作為最被廣泛使用、最久經考驗、穩定性最高的Redis代理,在業界被廣泛使用。

    (3)Codis

    Twemproxy不能平滑增加Redis例項的問題帶來了很大的不便,於是豌豆莢自主研發了Codis,一個支持平滑增加Redis例項的Redis代理軟體,其基於Go和C語言開發,並於2014年11月在GitHub上開源。

    在Codis的架構圖中,Codis引入了Redis Server Group,其透過指定一個主CodisRedis和一個或多個從CodisRedis,實作了Redis集群的高可用。當一個主CodisRedis掛掉時,Codis不會自動把一個從CodisRedis提升為主CodisRedis,這涉及數據的一致性問題(Redis本身的數據同步是采用主從異步復制,當數據在主CodisRedis寫入成功時,從CodisRedis是否已讀入這個數據是沒法保證的),需要管理員在管理界面上手動把從CodisRedis提升為主CodisRedis。

    如果手動處理覺得麻煩,豌豆莢也提供了一個工具Codis-ha,這個工具會在檢測到主CodisRedis掛掉的時候將其下線並提升一個從CodisRedis為主CodisRedis。

    Codis中采用預分片的形式,啟動的時候就建立了1024個slot,1個slot相當於1個箱子,每個箱子有固定的編號,範圍是1~1024。slot這個箱子用作存放Key,至於Key存放到哪個箱子,可以透過演算法「crc32(key)24」獲得一個數位,這個數位的範圍一定是1~1024之間,Key就放到這個數位對應的slot。

    例如,如果某個Key透過演算法「crc32(key)24」得到的數位是5,就放到編碼為5的slot(箱子)。1個slot只能放1個Redis Server Group,不能把1個slot放到多個Redis Server Group中。1個Redis Server Group最少可以存放1個slot,最大可以存放1024個slot。因此,Codis中最多可以指定1024個Redis Server Group。

    Codis最大的優勢在於支持平滑增加(減少)Redis Server Group(Redis例項),能安全、透明地遷移數據,這也是Codis 有別於Twemproxy等靜態分布式 Redis 解決方案的地方。Codis增加了Redis Server Group後,就牽涉到slot的遷移問題。

    例如,系統有兩個Redis Server Group,Redis Server Group和slot的對應關系如下。

    當增加了一個Redis Server Group,slot就要重新分配了。Codis分配slot有兩種方法:

    第一種:透過Codis管理工具Codisconfig手動重新分配,指定每個Redis Server Group所對應的slot的範圍,例如:可以指定Redis Server Group和slot的新的對應關系如下。

    第二種:透過Codis管理工具Codisconfig的rebalance功能,會自動根據每個Redis Server Group的記憶體對slot進行遷移,以實作數據的均衡。

    Redis Cluster

    Redis 的哨兵模式雖然已經可以實作高可用,讀寫分離 ,但是存在幾個方面的不足:

  • 哨兵模式下每台 Redis 伺服器都儲存相同的數據,很浪費記憶體空間;數據量太大,主從同步時嚴重影響了master效能。

  • 哨兵模式是中心化的集群實作方案,每個從機和主機的耦合度很高,master宕機到salve選舉master恢復期間服務不可用。

  • 哨兵模式始終只有一個Redis主機來接收和處理寫請求,寫操作還是受單機瓶頸影響,沒有實作真正的分布式架構。

  • redis在3.0上加入了 Cluster 集群模式,實作了 Redis 的分布式儲存,也就是說每台 Redis 節點上儲存不同的數據。cluster模式為了解決單機Redis容量有限的問題,將數據按一定的規則分配到多台機器,記憶體/QPS不受限於單機,可受益於分布式集群高擴充套件性。

    Redis Cluster是一種伺服器Sharding技術(分片和路由都是在伺服端實作),采用內送流量備援容錯機制多從,每一個分區都是由一個Redis主機和多個從機組成,片區和片區之間是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。

    如上圖,官方推薦,集群部署至少要 3 台以上的master節點,最好使用 3 主 3 從六個節點的模式。Redis Cluster集群具有如下幾個特點:

  • 集群完全去中心化,采用內送流量備援容錯機制多從;所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協定最佳化傳輸速度和頻寬。

  • 客戶端與 Redis 節點直連,不需要中間代理層。客戶端不需要連線集群所有節點,連線集群中任何一個可用節點即可。

  • 每一個分區都是由一個Redis主機和多個從機組成,分片和分片之間是相互平行的。

  • 每一個master節點負責維護一部份槽,以及槽所對映的鍵值數據;集群中每個節點都有全量的槽資訊,透過槽每個node都知道具體數據儲存到哪個node上。

  • redis cluster主要是針對海量數據+高並行+高可用的場景,海量數據,如果你的數據量很大,那麽建議就用redis cluster,數據量不是很大時,使用sentinel就夠了。redis cluster的效能和高可用性均優於哨兵模式。

    Redis Cluster采用虛擬哈希槽分區而非一致性hash演算法,預先分配一些卡槽,所有的鍵根據哈希函式對映到這些槽內,每一個分區內的master節點負責維護一部份槽以及槽所對映的鍵值數據。

    來源 :blog.csdn.net/Seky_fei/article/details/107239765

    >>

    END

    精品資料,超贊福利,免費領

    微信掃碼/長按辨識 添加【技術交流群

    群內每天分享精品學習資料

    最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎並行JVMMySQLRedisSpringSpringMVCSpringBootSpringCloud訊息佇列等多個型別),歡迎您的使用。

    👇👇

    👇點選"閱讀原文",獲取更多資料(持續更新中