深入瞭解redis叢集方案(主從模式、哨兵模式、Redis Cluster模式)

2022-03-24 22:01:16
本篇文章給大家帶來了關於的相關知識,其中主要介紹了主從模式、哨兵模式以及Redis Cluster模式的相關問題,希望對大家有幫助。

推薦學習:

redis 叢集方案的介紹(主從模式、哨兵模式、Redis Cluster模式)

一、主從模式

將資料完全儲存在單個redis中主要存在兩個問題:

資料備份和資料體量較大造成的效能降低。
Redis的主從模式為這兩個問題提供了一個較好的解決方案。主從模式指的是使用一個redis範例作為主機,其餘的範例作為備份機。
主機和從機的資料完全一致,主機支援資料的寫入和讀取等各項操作,而從機則只支援與主機資料的同步和讀取,也就是說,使用者端可以將資料寫入到主機,由主機自動將資料的寫入操作同步到從機。
主從模式很好的解決了資料備份問題,並且由於主從服務資料幾乎是一致的,因而可以將寫入資料的命令傳送給主機執行,而讀取資料的命令傳送給不同的從機執行,從而達到讀寫分離的目的。

實現主從複製(Master-Slave Replication)的工作原理:

Slave從節點服務啟動並連線到Master之後,它將主動傳送一個SYNC命令。Master服務主節點收到同步命令後將啟動後臺存檔程序,同時收集所有接收到的用於修改資料集的命令,在後臺程序執行完畢後,Master將傳送整個資料庫檔案到Slave,以完成一次完全同步。而Slave從節點服務在接收到資料庫檔案資料之後將其存檔並載入到記憶體中。此後,Master主節點繼續將所有已經收集到的修改命令,和新的修改命令依次傳送給Slaves,Slave將在本次執行這些資料修改命令,從而達到最終的資料同步。
如果Master和Slave之間的連結出現斷連現象,Slave可以自動重連Master,在連線成功之後,一次完全同步將被自動執行。
在這裡插入圖片描述

部署:

redis version:6.0.9

1.分別複製4份Redis組態檔

命名為 master.conf slave1.conf slave2.conf slave3.conf

2.對4份組態檔進行簡單設定
Master節點的組態檔一般不需要特殊設定 port預設為6379
Slave1 節點 port設定 6380 再設定一行 replicaof 127.0.0.1 6379
Slave2 節點 port設定 6381 再設定一行 replicaof 127.0.0.1 6379
Slave3 節點 port設定 6382 再設定一行 replicaof 127.0.0.1 6379

3.分別開啟 Master節點和3個Slave節點

redis-server master.conf
redis-server slave1.conf
redis-server slave2.conf
redis-server slave3.conf

4.驗證叢集主從狀態

在這裡插入圖片描述
在這裡插入圖片描述

主從模式的優缺點:

1、優點:

同一個Master可以同步多個Slaves。
master能自動將資料同步到slave,可以進行讀寫分離,分擔master的讀壓力
master、slave之間的同步是以非阻塞的方式進行的,同步期間,使用者端仍然可以提交查詢或更新請求
2、缺點:

不具備自動容錯與恢復功能,master或slave的宕機都可能導致使用者端請求失敗,需要等待機器重新啟動或手動切換使用者端IP才能恢復
master宕機,如果宕機前資料沒有同步完,則切換IP後會存在資料不一致的問題
難以支援線上擴容,Redis的容量受限於單機設定
其實redis的主從模式很簡單,在實際的生產環境中很少使用,不建議在實際的生產環境中使用主從模式來提供系統的高可用性,之所以不建議使用都是由它的缺點造成的,在資料量非常大的情況,或者對系統的高可用性要求很高的情況下,主從模式也是不穩定的。雖然這個模式很簡單,但是這個模式是其他模式的基礎,所以理解了這個模式,對其他模式的學習會很有幫助。

二、哨兵模式(Sentinel)

哨兵顧名思義,就是來為Redis叢集站哨的,一旦發現問題能做出相應的應對處理。其功能包括
監控master、slave是否正常執行
當master出現故障時,能自動將一個slave轉換為master(大哥掛了,選一個小弟上位)
多個哨兵可以監控同一個Redis,哨兵之間也會自動監控

當自動發現slave和其他哨兵節點後,哨兵就可以通過定期傳送PING命令定時監控這些資料庫和節點有沒有停止服務。
如果被PING的資料庫或者節點超時(通過 sentinel down-after-milliseconds master-name milliseconds 設定)未回覆,哨兵認為其主觀下線(sdown,s就是Subjectively —— 主觀地)。如果下線的是master,哨兵會向其它哨兵傳送命令詢問它們是否也認為該master主觀下線,如果達到一定數目(即組態檔中的quorum)投票,哨兵會認為該master已經客觀下線(odown,o就是Objectively —— 客觀地),並選舉領頭的哨兵節點對主從系統發起故障恢復。若沒有足夠的sentinel程序同意master下線,master的客觀下線狀態會被移除,若master重新向sentinel程序傳送的PING命令返回有效回覆,master的主觀下線狀態就會被移除。

哨兵認為master客觀下線後,故障恢復的操作需要由選舉的領頭哨兵來執行,
選出領頭哨兵後,領頭者開始對系統進行故障恢復,從出現故障的master的從資料庫中挑選一個來當選新的master,
挑選出需要繼任的slave後,領頭哨兵向該資料庫傳送命令使其升格為master,然後再向其他slave傳送命令接受新的master,最後更新資料。將已經停止的舊的master更新為新的master的從資料庫,使其恢復服務後以slave的身份繼續執行。
在這裡插入圖片描述

哨兵模式基於前面的主從複製模式。哨兵的組態檔為sentinel.conf,在相應目錄中新增以下設定,注意埠不要衝突:

port 26379
protected-mode no
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "/data/redis/logs/sentinel_26379.log"
dir "/data/redis/6379"
sentinel monitor mymaster 127.0.0.1 6379 2           ##指定主機IP地址和埠,並且指定當有2臺哨兵認為主機掛了,則對主機進行容災切換
#sentinel auth-pass mymaster pwdtest@2019             ##當在Redis範例中開啟了requirepass,這裡就需要提供密碼
sentinel down-after-milliseconds mymaster 3000                      ##這裡設定了主機多少秒無響應,則認為掛了
sentinel failover-timeout mymaster 180000       ##故障轉移的超時時間,這裡設定為三分鐘

格式如下:

在這裡插入圖片描述

檢視哨兵狀態:
在這裡插入圖片描述

三、redis 叢集模式(Cluster)

在這裡插入圖片描述

Cluster採用無中心結構,它的特點如下:
使用者端與redis節點直連,使用者端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可

Cluster模式的具體工作機制:
在Redis的每個節點上,都有一個插槽(slot),取值範圍為0-16383 ,一共16384個槽
當我們存取key的時候,Redis會根據CRC16的演演算法得出一個結果,然後把結果對16384求餘數,這樣每個key都會對應一個編號在0-16383之間的雜湊槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。

為了保證高可用,Cluster模式也引入主從複製模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。

當其它主節點ping一個主節點A時,如果半數以上的主節點與A通訊超時,那麼認為主節點A宕機了。如果主節點A和它的從節點都宕機了,那麼該叢集就無法再提供服務了。

Redis叢集,要保證16384個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,整個叢集將不能工作。
為了增加叢集的可存取性,官方推薦的方案是將node設定成主從結構,即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演演算法從slave節點中選擇一個上升為主節點,整個叢集繼續對外提供服務,Redis Cluster本身提供了故障轉移容錯的能力。

Cluster模式叢集節點最小設定6個節點(根據cluster的選舉機制和主從備份的實現,redis要求至少三主三從共6個節點才能組成redis叢集,因為至少需要半數以上才能確定某個節點是否宕機且需要主從備份),其中主節點提供讀寫操作,從節點作為備用節點,不提供請求,只作為故障轉移使用。

cluster叢集部署
根據cluster的選舉機制和主從備份的實現,redis要求至少三主三從共6個節點才能組成redis叢集,測試環境可一臺物理機器上啟動6個redis節點,但生產環境至少要準備2~3臺物理機。(這裡使用三臺虛擬機器器)

Cluster模式是建立在Sentinel模式的基礎上的,當資料多到需要動態擴容的時候,前面兩種就不行了,需要對資料進行分片,根據一定的規則把redis資料分配到多臺機器。
在這裡插入圖片描述

該模式就支援動態擴容,可以線上增加或刪除節點,而且使用者端可以連線任何一個主節點進行讀寫,不過此時的從節點僅僅只是備份的作用。至於為何能做到動態擴容,主要是因為Redis叢集沒有使用一致性hash,而是使用的雜湊槽。Redis叢集會有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,而叢集的每個節點負責一部分hash槽。

那麼這樣就很容易新增或者刪除節點, 比如如果我想新新增個新節點, 我只需要從已有的節點中的部分槽到過來;如果我想移除某個節點,就只需要將該節點的槽移到其它節點上,然後將沒有任何槽的A節點從叢集中移除即可。由於從一個節點將雜湊槽移動到另一個節點並不會停止服務,所以無論新增刪除或者改變某個節點的雜湊槽的數量都不會造成叢集不可用的狀態。

需要注意的是,該模式下不支援同時處理多個key(如MSET/MGET),因為redis需要把key均勻分佈在各個節點上,並行量很高的情況下同時建立key-value會降低效能並導致不可預測的行為。

搭建叢集

這裡就直接搭建較為複雜的Cluster模式叢集,也是企業級開發過程中使用最多的。

1.建redis各節點目錄

最終目錄結構如下
在這裡插入圖片描述

2.逐個修改redis設定

以 9001 的為例子,其餘五個類似。

編輯 /data/redis-cluster/9001/redis.conf

redis.conf修改如下:

port 9001(每個節點的埠號)
daemonize yes
appendonly yes  //開啟aof
bind 0.0.0.0(繫結當前機器 IP)
dir "/data/redis-cluster/9001"(資料檔案存放位置,,自己加到最後一行 快捷鍵 shift+g)
pidfile /var/run/redis_9001.pid(pid 9001和port要對應)
logfile "/data/redis-cluster/logs/9001.log"
cluster-enabled yes(啟動叢集模式)
cluster-config-file nodes9001.conf(9001和port要對應)
cluster-node-timeout 15000
3.逐個啟動redis節點

/data/redis-cluster/bin/redis-server /data/redis-cluster/9001/redis.conf

/data/redis-cluster/bin/redis-server /data/redis-cluster/9002/redis.conf

/data/redis-cluster/bin/redis-server /data/redis-cluster/9003/redis.conf

/data/redis-cluster/bin/redis-server /data/redis-cluster/9004/redis.conf

/data/redis-cluster/bin/redis-server /data/redis-cluster/9005/redis.conf

/data/redis-cluster/bin/redis-server /data/redis-cluster/9006/redis.conf

現在檢查一下是否成功開啟,如下圖所示,都開啟成功。

ps -el | grep redis

在這裡插入圖片描述

4.叢集設定

此時的節點雖然都啟動成功了,但他們還不在一個叢集裡面,不能互相發現,測試會報錯:(error) CLUSTERDOWN Hash slot not served。

如下圖所示

在這裡插入圖片描述

redis-cli --cluster create 10.32.176.80:9001 10.32.176.80:9002 10.32.176.80:9003 10.32.176.80:9004 10.32.176.80:9005 10.32.176.80:9006 --cluster-replicas 1

–cluster-replicas 1 這個指的是從機的數量,表示我們希望為叢集中的每個主節點建立一個從節點。

紅色選框是給三個主節點分配的共16384個槽點。

黃色選框是主從節點的分配情況。

藍色選框是各個節點的詳情。

在這裡插入圖片描述

5.測試

現在通過使用者端命令連線上,通過叢集命令看一下狀態和節點資訊等

/data/redis-cluster/bin/redis-cli -c -h 10.32.176.80 -p 9001

cluster info

cluster nodes

效果圖如下,叢集搭建成功。

在這裡插入圖片描述

現在往9001這個主節點寫入一條資訊,我們可以在9002這個主節點取到資訊,叢集間各個節點可以通訊。

6.故障轉移

故障轉移機制詳解

叢集中的節點會向其它節點傳送PING訊息(該PING訊息會帶著當前叢集和節點的資訊),如果在規定時間內,沒有收到對應的PONG訊息,就把此節點標記為疑似下線。當被分配了slot槽位的主節點中有超過一半的節點都認為此節點疑似下線(就是其它節點以更高的頻次,更頻繁的與該節點PING-PONG),那麼該節點就真的下線。其它節點收到某節點已經下線的廣播後,把自己內部的叢集維護資訊也修改為該節點已事實下線。

節點資格審查:然後對從節點進行資格審查,每個從節點檢查最後與主節點的斷線時間,如果該值超過組態檔的設定,那麼取消該從節點的資格。準備選舉時間:這裡使用了延遲觸發機制,主要是給那些延遲低的更高的優先順序,延遲低的讓它提前參與被選舉,延遲高的讓它靠後參與被選舉。(延遲的高低是依據之前與主節點的最後斷線時間確定的)

選舉投票:當從節點獲取選舉資格後,會向其他帶有slot槽位的主節點發起選舉請求,由它們進行投票,優先順序越高的從節點就越有可能成為主節點,當從節點獲取的票數到達一定數值時(如叢集內有N個主節點,那麼只要有一個從節點獲得了N/2+1的選票即認為勝出),就會替換成為主節點。

替換主節點:被選舉出來的從節點會執行slaveof no one把自己的狀態從slave變成master,然後執行clusterDelSlot操作復原故障主節點負責的槽,並執行 clusterAddSlot把這些槽分配給自己,之後向叢集廣播自己的pong訊息,通知叢集內所有的節點,當前從節點已變為主節點。

接管相關操作:新的主節點接管了之前故障的主節點的槽資訊,接收和處理與自己槽位相關的命令請求。

故障轉移測試

這是之前叢集中具體節點的情況,我簡化成如下,可以向上回看圖片中的叢集資訊。

在這裡插入圖片描述

這裡關閉該9001埠的程序,即模擬該主節點掛掉。

登入掛掉的redis節點,會被拒絕服務,通過還在正常執行的某個主節點進入,然後再次檢視叢集中的資訊

在這裡插入圖片描述

簡而言之,就是之前的叢集資訊變成了如下所示

在這裡插入圖片描述
在這裡插入圖片描述

現在,我重新啟動剛才掛掉的主節點,重新檢視叢集內部的節點情況,具體情況如下圖所示

在這裡插入圖片描述

簡而言之,現在叢集內的節點情況如下

在這裡插入圖片描述

推薦學習:

以上就是深入瞭解redis叢集方案(主從模式、哨兵模式、Redis Cluster模式)的詳細內容,更多請關注TW511.COM其它相關文章!