redis集群三主三從原理「redis集群部署方式」

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

Redis 也是一樣,為了解決單機故障引入了主從模式,但主從模式存在一個問題:master 節點故障後服務,需要人為的手動將 slave 節點切換成為 master 節點後服務才恢復。Redis 為解決這一問題又引入了哨兵模式,哨兵模式能在 master 節點故障後能自動將 slave 節點提升成 master 節點,不需要人工干預操作就能恢復服務可用。但是主從模式、哨兵模式都沒有達到真正的數據 sharding 存儲,每個 Redis 實例中存儲的都是全量數據,所以 Redis cluster 就誕生了,實現了真正的數據分片存儲。但是由於 Redis cluster 發布得比較晚(2015 年才發布正式版 ),各大廠等不及了,陸陸續續開發了自己的 Redis 數據分片集群模式,比如:Twemproxy、Codis 等。

主從模式

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

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

談談Redis的各種集群方案、及優缺點對比

Redis一主多從

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

主從模式優缺點

  • 「優點:」 主從結構具有讀寫分離,提高效率、數據備份,提供多個副本等優點。
  • 「不足:」 最大的不足就是主從模式不具備自動容錯和恢復功能,主節點故障,集群則無法進行工作,可用性比較低,從節點升主節點需要人工手動干預。

普通主從

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

  1. 在從資料庫中使用 SLAVE NO ONE 命令將從資料庫提升成主數據繼續服務。
  2. 啟動之前崩潰的主資料庫,然後使用 SLAVEOF 命令將其設置成新的主資料庫的從資料庫,即可同步數據。

哨兵模式

第一種主從同步/複製的模式,當主伺服器宕機後,需要手動把一台從伺服器切換為主伺服器,這就需要人工干預,費事費力,還會造成一段時間內服務不可用,這時候就需要哨兵模式登場了。哨兵模式是從 Redis 的 2.6 版本開始提供的,但是當時這個版本的模式是不穩定的,直到 Redis 的 2.8 版本以後,這個哨兵模式才穩定下來。

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

談談Redis的各種集群方案、及優缺點對比

Redis哨兵模式

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

談談Redis的各種集群方案、及優缺點對比

多哨兵互相監控

哨兵模式的作用:

  • 監控所有伺服器是否正常運行:通過發送命令返回監控伺服器的運行狀態,處理監控主伺服器、從伺服器外,哨兵之間也相互監控。
  • 故障切換:當哨兵監測到 master 宕機,會自動將 slave 切換成 master,然後通過「發布訂閱模式」通知其他的從伺服器,修改配置文件,讓它們切換 master。同時那台有問題的舊主也會變為新主的從,也就是說當舊的主即使恢復時,並不會恢復原來的主身份,而是作為新主的一個從。

哨兵實現原理

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

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

這裡之所以只需要連接主節點,是因為通過主節點的 info 命令,獲取從節點信息,從而和從節點也建立連接,同時也能通過主節點的 info 信息知道新增從節點的信息。

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

  1. 訂閱主資料庫 _sentinel_:hello 頻道以獲取同樣監控該資料庫的哨兵節點信息
  2. 定期向主資料庫發送 info 命令,獲取主資料庫本身的信息。

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

  • 每隔 10s 向 master 和 slave 發送 info 命令。作用是獲取當前資料庫信息,比如發現新增從節點時,會建立連接,並加入到監控列表中,當主從資料庫的角色發生變化進行信息更新。
  • 每隔 2s 向主數據里和從資料庫的 _sentinel_:hello 頻道發送自己的信息。作用是將自己的監控數據和哨兵分享。每個哨兵會訂閱資料庫的_sentinel:hello 頻道,當其他哨兵收到消息後,會判斷該哨兵是不是新的哨兵,如果是則將其加入哨兵列表,並建立連接。
  • 每隔 1s 向所有主從節點和所有哨兵節點發送 ping 命令,作用是監控節點是否存活。

主觀下線和客觀下線

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

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

  • 選出領頭哨兵。
  • 領頭哨兵所有的 slave 選出優先順序最高的從資料庫。優先順序可以通過 slave-priority 選項設置。
  • 如果優先順序相同,則從複製的命令偏移量越大(即複製同步數據越多,數據越新),越優先。
  • 如果以上條件都一樣,則選擇 run ID 較小的從資料庫。

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

哨兵模式優缺點

  1. 優點 哨兵模式是基於主從模式的,解決可主從模式中master故障不可以自動切換故障的問題。
  2. 不足-問題 (1)是一種中心化的集群實現方案:始終只有一個 Redis 主機來接收和處理寫請求,寫操作受單機瓶頸影響。(2)集群里所有節點保存的都是全量數據,浪費內存空間,沒有真正實現分散式存儲。數據量過大時,主從同步嚴重影響 master 的性能。(3)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 實例。

客戶端分片

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

談談Redis的各種集群方案、及優缺點對比

ShardedJedis分片方案

客戶端分片的優缺點:

  • 優點:客戶端 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 實例群拓撲結構有變化時,每個客戶端都需要更新調整。如果能把客戶端分片模塊單獨拎出來,形成一個單獨的模塊(中間件),作為客戶端 和 服務端連接的橋樑就能解決這個問題了,此時「代理分片」就出現了。

代理分片

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

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

談談Redis的各種集群方案、及優缺點對比

Redis代理分片

「Twemproxy 的優點:」

  • 客戶端相連接 Redis 實例一樣連接 Twemproxy,不需要改任何的代碼邏輯。
  • 支持無效 Redis 實例的自動刪除。
  • Twemproxy 與 Redis 實例保持連接,減少了客戶端與 Redis 實例的連接數。

「Twemproxy 的不足:」

  • 由於 Redis 客戶端的每個請求都經過 Twemproxy 代理才能到達 Redis 伺服器,這個過程中會產生性能損失。
  • 沒有友好的監控管理後台界面,不利於運維監控。
  • Twemproxy 最大的痛點在於,無法平滑地擴容/縮容。對於運維人員來說,當因為業務需要增加 Redis 實例時工作量非常大。

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

Codis

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

談談Redis的各種集群方案、及優缺點對比

Codis Proxy高可用集群

在 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)%1024獲得一個數字,這個數字的範圍一定是 1~1024 之間,Key 就放到這個數字對應的 slot。例如,如果某個 Key 通過演算法crc32(key)%1024得到的數字是 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的各種集群方案、及優缺點對比

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

  • 第一種:通過 Codis 管理工具 Codisconfig 手動重新分配,指定每個 Redis Server Group 所對應的 slot 的範圍,例如:可以指定 Redis Server Group 和 slot 的新的對應關係如下。
談談Redis的各種集群方案、及優缺點對比
  • 第二種:通過 Codis 管理工具 Codisconfig 的 rebalance 功能,會自動根據每個 Redis Server Group 的內存對 slot 進行遷移,以實現數據的均衡。

Redis Cluster

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

  • 哨兵模式下每台 Redis 伺服器都存儲相同的數據,很浪費內存空間;數據量太大,主從同步時嚴重影響了 master 性能。
  • 哨兵模式是中心化的集群實現方案,每個從機和主機的耦合度很高,master 宕機到 slave 選舉 master 恢復期間服務不可用。
  • 哨兵模式始終只有一個 Redis 主機來接收和處理寫請求,寫操作還是受單機瓶頸影響,沒有實現真正的分散式架構。

Redis 在 3.0 上加入了 Cluster 集群模式,實現了 Redis 的分散式存儲,也就是說每台 Redis 節點上存儲不同的數據。cluster 模式為了解決單機 Redis 容量有限的問題,將數據按一定的規則分配到多台機器,內存/QPS 不受限於單機,可受益於分散式集群高擴展性。Redis Cluster 是一種伺服器 Sharding 技術(分片和路由都是在服務端實現),「採用多主多從,每一個分區都是由一個 Redis 主機和多個從機組成,片區和片區之間是相互平行的」。Redis Cluster 集群採用了 P2P 的模式,完全去中心化。

談談Redis的各種集群方案、及優缺點對比

Redis Cluster 集群模式

如上圖,官方推薦,集群部署至少要 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 節點負責維護一部分槽以及槽所映射的鍵值數據。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/259009.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-15 16:29
下一篇 2024-12-15 16:29

相關推薦

發表回復

登錄後才能評論