範例詳解redis怎麼部署叢集

2022-03-23 22:00:46
本篇文章給大家帶來了關於redis的相關知識,其中主要介紹了叢集部署的相關問題,包括了主從架構、哨兵高可用架構以及高可用叢集等等,希望對大家有幫助。

推薦學習:

1、Redis主從架構

在這裡插入圖片描述

1.1、主從複製原理

  • 從伺服器連線主伺服器,傳送PSYNC命令;

  • 主伺服器接收到PSYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;

  • 主伺服器BGSAVE執行完後,向所有從伺服器傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;

  • 從伺服器收到快照檔案後丟棄所有舊資料,載入收到的快照;

  • 主伺服器快照傳送完畢後開始向從伺服器傳送緩衝區中的寫命令;

  • 從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;(從伺服器初始化完成)

  • 主伺服器每執行一個寫命令就會向從伺服器傳送相同的寫命令,從伺服器接收並執行收到的寫命令(從伺服器初始化完成後的操作)

  • 當master與slave之間的連線由於某些原因而斷開時,slave能夠自動重連Master,如果master收到了多個slave並行連線請求,它只會進行一次持久化,而不是一個連線一次,然後再把這一份持久化的資料傳送給多個並行連線的slave。

在這裡插入圖片描述

1.2、主從複製優缺點

優點:

  • 支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離

  • 為了分載Master的讀操作壓力,Slave伺服器可以為使用者端提供唯讀操作的服務,寫服務仍然必須由Master來完成

  • Slave同樣可以接受其它Slaves的連線和同步請求,這樣可以有效的分載Master的同步壓力。

  • Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,使用者端仍然可以提交查詢或修改請求。

  • Slave Server同樣是以非阻塞的方式完成資料同步。在同步期間,如果有使用者端提交查詢請求,Redis則返回同步之前的資料

缺點:

  • Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重新啟動或者手動切換前端的IP才能恢復。

  • 主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性。

  • Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

1.3、redis主從架構搭建,設定從節點步驟

此處使用6380作為master節點 6381和6382作為slave節點

#1、 建立目錄 conf/master-slave-cluster 存放對應叢集的設定資訊mkdir -p conf/master-slave-cluster# 建立目錄 data 存放對應叢集對應的資料資訊(資料目錄)mkdir -p /usr/local/redis/data/6380 
mkdir -p /usr/local/redis/data/6381 
mkdir -p /usr/local/redis/data/6382 
#複製一份redis.conf檔案 重新命名redis-6381.conf# 2、將相關設定修改為如下值:# 修改埠號port 6381# 把pid程序號寫入pidfile設定的檔案pidfile /var/run/redis_6381.pid  
# 指定紀錄檔存放目錄logfile "6381.log"# 指定資料存放目錄dir /usr/local/redis-5.0.3/data/6381 

# 需要註釋掉bind# bind 127.0.0.1(bind繫結的是自己機器網路卡的ip,如果有多塊網路卡可以配多個ip,代表允許使用者端通過機器的哪些網路卡ip去存取,內網一般可以不設定bind,註釋掉即可)# 3、設定主從複製(6380是master不需要設定如下 只需給6381和6382設定如下屬性)# 從本機6379的redis範例複製資料,Redis 5.0之前使用slaveofreplicaof xxx.xxx.xxx.xxx 6380  # 設定從節點唯讀replica-read-only yes  #4、啟動從節點redis-server redis-6381.conf5、連線從節點
redis-cli -p 63816、測試在6380範例上寫資料,6381範例是否能及時同步新修改資料7、同樣的方法再設定一個6382的從節點

1.4、校驗結果

檢視redis的主從叢集
在這裡插入圖片描述

master操作

# 連線master[root@ip redis]# src/redis-cli -p 6380127.0.0.1:6380> auth xiu123
OK127.0.0.1:6380> set name "zhangsan"OK127.0.0.1:6380> get name 
"zhangsan"

在這裡插入圖片描述

slave操作

# 連線slavesrc/redis-cli -p 6381127.0.0.1:6381> get name 
"zhangsan"#從節點只能進行讀操作127.0.0.1:6381> set name lisi(error) READONLY You can't write against a read only replica.127.0.0.1:6381> ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/36d9e96b1cae498fad03e04d695997c2.png#pic_center)

在這裡插入圖片描述

1.5、資料部分複製

當master和slave斷開重連後,一般都會對整份資料進行復制。但從redis2.8版本開始,redis改用可以支援部分資料複製的命令PSYNC去master同步資料,slave與master能夠在網路連線斷開重連後只進行部分資料複製(斷點續傳)。

master會在其記憶體中建立一個複製資料用的快取佇列,快取最近一段時間的資料,master和它所有的slave都維護了複製的資料下標offset和master的程序id,因此,當網路連線斷開後,slave會請求master繼續進行未完成的複製,從所記錄的資料下標開始。如果master程序id變化了,或者從節點資料下標offset太舊,已經不在master的快取佇列裡了,那麼將會進行一次全量資料的複製。

主從複製(部分複製,斷點續傳)流程圖:

在這裡插入圖片描述

如果有很多從節點,為了緩解主從複製風暴**(多個從節點同時複製主節點導致主節點壓力過大),可以做如下架構,讓部分從節點與從節點(與主節點同步)同步資料

2、Redis哨兵高可用架構

在這裡插入圖片描述

sentinel哨兵是特殊的redis服務,不提供讀寫服務,主要用來監控redis範例節點。哨兵的作用就是監控Redis系統的執行狀況。它的功能包括以下兩個

(1)監控主伺服器和從伺服器是否正常執行。

(2)主伺服器出現故障時自動將從伺服器轉換為主伺服器。

2.1、哨兵的工作方式

  1. 哨兵架構下client端第一次從哨兵找出redis的主節點,後續就直接存取redis的主節點,當redis的主節點發生變化,哨兵會第一時間感知到,並且將新的redis主節點通知給client端。
  2. Sentinel 會定時的對自己監控的 master 執行 info 命令,獲取最新的主從關係,還會定時的給所有的 redis 節點傳送 ping 心跳檢測命令,如果檢測到某個 master 無法響應了,就會在給其他 Sentinel 傳送訊息,主觀認為該 master 宕機,如果 Sentinel 叢集認同該 master 下線的人數達到一個值,那麼大家統一意見,下線該 master。
  3. 下線之前需要做的是找 Sentinel 叢集中的某一個來執行下線操作,這個步驟叫領導者選舉,選出來以後會從該 master 所有的 slave 節點中挑一個合適的作為新的 master,並讓其他 slave 重新同步新的 master
  4. 若沒有足夠數量的 Sentinel(哨兵)程序同意 Master主伺服器下線, Master主伺服器的客觀下線狀態就會被移除。若 Master主伺服器重新向 Sentinel(哨兵)程序傳送 PING 命令返回有效回覆,Master主伺服器的主觀下線狀態就會被移除。

三個定時任務
sentinel在內部有3個定時任務
1)每10秒每個sentinel會對master和slave執行info命令,這個任務達到兩個目的:
a)發現slave節點
b)確認主從關係
2)每2秒每個sentinel通過master節點的channel交換資訊(pub/sub)。master節點上有一個釋出訂閱的頻道(sentinel:hello)。sentinel節點通過__sentinel__:hello頻道進行資訊交換(對節點的"看法"和自身的資訊),達成共識。
3)每1秒每個sentinel對其他sentinel和redis節點執行ping操作(相互監控),這個其實是一個心跳檢測,是失敗判定的依據。

2.2、哨兵模式的優缺點

優點:

哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。

主從可以自動切換,系統更健壯,可用性更高。

缺點:

Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

2.3、redis哨兵架構搭建步驟

2.3.1、設定sentinel.conf檔案
# 1、複製一份sentinel.conf檔案mkdir sentinelcp sentinel.conf sentinel-26380.conf
# 保護模式protected-mode no
# 埠號port 26380# 是否靜默啟動daemonize yes
# pid程序號pidfile "/var/run/redis-sentinel-26380.pid"
# 紀錄檔檔案logfile "/usr/local/redis/data/6380/sentinel.log"
# 哨兵服務資料儲存dir "/usr/local/redis/data"
# 哨兵監控 sentinel monitor <masterName> <maste節點redis ip> <num 哨兵認可主觀下線數量>
# 故障轉移後  master節點ip會發生變化sentinel monitor mymaster 182.92.189.235 6380 2
# 連線master節點 密碼# 設定連線master和slave時的密碼,注意的是sentinel不能分別為master和slave設定不同的密碼,因此master和slave的密碼應該設定相同。sentinel auth-pass mymaster xiu123#sentinel config-epoch mymaster 9#sentinel leader-epoch mymaster 9# 自動生成 從節點資訊 但是此處沒有自動生成sentinel known-slave mymaster 182.92.189.235 6381sentinel known-slave mymaster 182.92.189.235 6382
# 自動生成設定 啟動回自動生成一些設定
2.3.2、啟動哨兵服務範例
#啟動sentinel哨兵範例src/redis-sentinel sentinel-26380.conf
#檢視sentinel的info資訊src/redis-cli -p 26379127.0.0.1:26379>info
#可以看到Sentinel的info裡已經識別出了redis的主從
#同理再次新增兩個sentinel,埠26381和26382 並同理啟動,注意上述組態檔裡的對應數位都要修改

在這裡插入圖片描述

sentinel叢集都啟動完畢後,會將哨兵叢集的後設資料資訊寫入所有sentinel的組態檔裡去(追加在檔案的最下面),我們檢視下如下組態檔sentinel-26380.conf,如下所示:
在這裡插入圖片描述

2.3.3、redis哨兵模式故障遷移
"shell
# 1、檢視當前redis 叢集服務 一主兩從三哨兵
[root@iZ2ze505h9bgsa1t9twojyZ redis]# ps -ef | grep redis
root      1166 30926  0 22:43 pts/2    00:00:00 grep --color=auto redis
root     28998     1  0 21:12 ?        00:00:06 src/redis-server *:6380
root     29010     1  0 21:12 ?        00:00:06 src/redis-server *:6381
root     29020     1  0 21:12 ?        00:00:06 src/redis-server *:6382
root     31686     1  0 22:05 ?        00:00:05 src/redis-sentinel *:26380 [sentinel]
root     32553     1  0 22:22 ?        00:00:03 src/redis-sentinel *:26381 [sentinel]
root     32562     1  0 22:22 ?        00:00:03 src/redis-sentinel *:26382 [sentinel]
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6380
127.0.0.1:6380> auth xiu123
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=182.92.189.235,port=6381,state=online,offset=261525,lag=0
slave1:ip=182.92.189.235,port=6382,state=online,offset=261525,lag=1
... 省略部分程式碼

127.0.0.1:6380> quit

# 殺掉 redis
[root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 28998
# 檢視紀錄檔
[root@iZ2ze505h9bgsa1t9twojyZ redis]# tail -f data/6380/sentinel.log 
# 該哨兵認為主觀下線
31686:X 12 Nov 2021 22:45:40.110 # +sdown master mymaster 182.92.189.235 6382
# 到達主觀下線闕值 則客觀下線
31686:X 12 Nov 2021 22:45:40.181 # +odown master mymaster 182.92.189.235 6382 #quorum 2/2
31686:X 12 Nov 2021 22:45:40.181 # +new-epoch 18
# 嘗試故障轉移
31686:X 12 Nov 2021 22:45:40.181 # +try-failover master mymaster 182.92.189.235 6382
# 投票選舉主節點
31686:X 12 Nov 2021 22:45:40.189 # +vote-for-leader ba9eed52de8664c3fd8d76d9728b42a309c3401b 18
# 選擇主節點 6381
31686:X 12 Nov 2021 22:45:41.362 # +switch-master mymaster 182.92.189.235 6382 182.92.189.235 6381

#檢視新的主從節點資訊 主節點6381 從節點6382
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6381
127.0.0.1:6381> auth xiu123
OK
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=182.92.189.235,port=6382,state=online,offset=469749,lag=0
    
"

3、Redis 高可用叢集

3.1、高可用叢集模式

在這裡插入圖片描述

3.2、Redis-Cluster叢集

redis的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每臺redis伺服器都儲存相同的資料,很浪費記憶體,所以在redis3.0上加入了cluster模式,實現的redis的分散式儲存,也就是說每臺redis節點上儲存不同的內容。

Redis-Cluster採用無中心結構,它的特點如下:

所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協定優化傳輸速度和頻寬。

節點的fail是通過叢集中超過半數的節點檢測失效時才生效。

使用者端與redis節點直連,不需要中間代理層.使用者端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可。

工作方式:

  • 在redis的每一個節點上,都有這麼兩個東西,一個是插槽(slot),它的的取值範圍是:0-16383。還有一個就是cluster,可以理解為是一個叢集管理的外掛。當我們的存取的key到達的時候,redis會根據crc16的演演算法得出一個結果(hash函數),然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。

  • 為了保證高可用,redis-cluster叢集引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通訊超時,那麼認為主節點A宕機了。如果主節點A和它的從節點A1都宕機了,那麼該叢集就無法再提供服務了。

  • redis叢集是一個由多個主從節點群組成的分散式伺服器群,它具有複製、高可用和分片特性。Redis叢集不需要sentinel哨兵·也能完成節點移除和故障轉移的功能。需要將每個節點設定成叢集模式,這種叢集模式沒有中心節點,可水平擴充套件,據官方檔案稱可以線性擴充套件到上萬個節點(官方推薦不超過1000個節點)。redis叢集的效能和高可用性均優於之前版本的哨兵模式,且叢集設定非常簡單

3.3、Redis高可用叢集搭建

3.3.1、redis叢集搭建

redis叢集需要至少三個master節點,我們這裡搭建三個master節點,並且給每個master再搭建一個slave節點,總共6個redis節點,這裡用三臺機器部署6個redis範例,每臺機器一主一從,搭建叢集的步驟如下:

6383(主) 6384(從)

6385(主) 6386(從)

6387(主) 6388(從)

節點設定
# 是否靜默啟動
daemonize yes
#埠號
port 6383

# pid程序檔案
pidfile /var/run/redis_6383.pid
#資料儲存
dir /usr/local/redis/data/redis-cluster/6383/

# 指定紀錄檔存放目錄
logfile "/usr/local/redis/data/cluster-6383.log"


#是否啟動叢集模式
cluster-enabled yes

#(叢集節點資訊檔案,這裡最好和port對應上)
cluster-config-file nodes-6383.conf
cluster-node-timeout 10000

# 關閉保護模式
protected-mode  no
建立叢集

redis叢集設定好後,在5.X版本之前需要需要使用ruby指令碼去建立叢集,但是5.x之後可以通過redis-cli 執行建立叢集命令即可

# 分別啟動redis範例
src/redis-server conf/cluster/638*/redis.conf

# 下面命令裡的1代表為每個建立的主伺服器節點建立一個從伺服器節點
# 執行這條命令需要確認三臺機器之間的redis範例要能相互存取,可以先簡單把所有機器防火牆關掉,如果不關閉防火牆則需要開啟redis伺服器埠和叢集節點gossip通訊埠16379(預設是在redis埠號上加1W)
# 關閉防火牆
# systemctl stop firewalld # 臨時關閉防火牆
# systemctl disable firewalld # 禁止開機啟動
# 注意:下面這條建立叢集的命令大家不要直接複製,裡面的空格編碼可能有問題導致建立叢集不成功 
# 本次測試不遠端連線 使用127.0.0.1 如果涉及遠端連線需要設定真實公網ip


# -a 密碼。  -- cluster create建立叢集  --cluster-replicas 1 每一個master建立一個從節點 6個範例 中選擇3個作為另外3個主節點的從節點,最終變成3主3從
src/redis-cli -a password --cluster create --cluster-replicas 1 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 127.0.0.1:6386 127.0.0.1:6387 127.0.0.1:6388

在這裡插入圖片描述

問題:

#1、這是由於建立叢集中的某一個服務中曾經插入過資料,並且已經產生了持久化檔案,重新再進行建立叢集 此時需要flushall命令清空所有資料
[ERR] Node 127.0.0.1:6383 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

#測試使用flush不好使用 只要找到組態檔對應資料儲存目錄 暴力rm刪除

# 2、登陸某個叢集出現 出現CLUSTERDOWN Hash slot not served 原因 啟動叢集範例後沒有執行叢集建立
驗證叢集

讀寫key需要 對key進行hash 不使用叢集模式登陸使用者端,則我們只存取單獨會提示讓我們去對應的節點上進行操作
在這裡插入圖片描述

叢集登陸

# 連線任意一個使用者端即可:./redis-cli -c -h -p (-a存取伺服器端密碼,-c表示叢集模式,指定ip地址和埠號)
# -a 密碼 -c 叢集模式  -h ip -p port
src/redis-cli -a password -c -h 127.0.0.1 -p 6383

在這裡插入圖片描述

#進行驗證: cluster info(檢視叢集資訊)、cluster nodes(檢視節點列表)
#進行資料操作驗證
#關閉叢集則需要逐個進行關閉,使用命令:
src/redis-cli -a password -c -h 127.0.0.1 -p 638* shutdown
3.3.2、叢集故障轉移

上述叢集三主三從 。6386、6387、6388分別對應主節點6383、6384、6385的從,如果某個主節點宕機,則從節點會自動被選舉為主節點繼續對外提供服務,一定的容錯機制保證高可用。注意存在從節點的情況下,主從節點不具備讀寫分離,讀寫都使用主節點

# 模擬redis的故障轉移

#登陸節點 發現 name這個key在6384上  age這個key在6383上 wdih這個key在6385上
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383
127.0.0.1:6384> get name
-> Redirected to slot [5798] located at 127.0.0.1:6384
(nil)
127.0.0.1:6384> get age
-> Redirected to slot [741] located at 127.0.0.1:6383
"12"
127.0.0.1:6383> get width
-> Redirected to slot [15983] located at 127.0.0.1:6385
"110"
127.0.0.1:6385> quit

## 殺掉 6385這個主節點
[root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 14187

# 重新登陸叢集 獲取 age、name 還是原來的節點 獲取width 由6385轉移到了6388  檢視6380節點資訊發現其變為了主節點
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383
127.0.0.1:6383> get age
"12"
# 這裡因該是在選舉master節點 導致叢集短暫不可用(猜測)
127.0.0.1:6383> get name
(error) CLUSTERDOWN The cluster is down
127.0.0.1:6383> get name
-> Redirected to slot [5798] located at 127.0.0.1:6384
"xieqx"

127.0.0.1:6384> get width
-> Redirected to slot [15983] located at 127.0.0.1:6388
"110"
127.0.0.1:6388> info replication
# Replication
role:master

# 殺掉 6388 則整個叢集服務都不可用
127.0.0.1:6383> get name
(error) CLUSTERDOWN The cluster is down
3.3.3、叢集動態擴縮容
#複製之前6383節點設定 建立6389、6390節點 並啟動範例

--- 叢集擴容 ----

#1、 新增master節點 
## add-node: 後面的分別跟著新加入的***master和叢集的某個節點 NODE_ID***
src/redis-cli --cluster add-node 127.0.0.1:6389 127.0.0.1:6383 -a password
# 2、為增加的主節點新增從節點 
#--cluster-slave 表明新增的是slave節點 
## add-node: 後面的分別跟著新加入的****slave和slave對應的master NODE_ID***
#--cluster-master-id:表示slave對應的master的node ID
src/redis-cli --cluster add-node 127.0.0.1:6390 127.0.0.1:6389 --cluster-slave --cluster-master-id 353662f6868b187ad15bad9b7271b8f0848adf10 -a password

# 3、 重新分片slot
#-cluster-from:表示slot目前所在的節點的node ID,多個ID用逗號分隔
#--cluster-to:表示需要新分配節點的node ID(貌似每次只能分配一個)
# --cluster-slots:分配的slot數量
src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 47318cef1195f4281b7815bf66a41e31d68b6d16,0dbea2fff1554a3bbca70d28b81911e60c5bee6d,2fd29d61e867cb85e2e368ee62aebef33e7aaeb3 --cluster-to 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-slots 1024 -a password

#檢視叢集資訊

在這裡插入圖片描述

 --- 叢集縮容 ----

#下線節點127.0.0.1:6389(master)/127.0.0.1:6390(slave)

#(1)首先刪除master對應的slave
#del-node後面跟著slave節點的 ip:port 和node ID
src/redis-cli --cluster del-node 127.0.0.1:6390 353662f6868b187ad15bad9b7271b8f0848adf10 -a password

#(2)清空master的slot 將一個下線的節點的slot重新分配到其他三個節點中
#reshard子命令前面已經介紹過了,這裡需要注意的一點是,由於我們的叢集一共有四個主節點,而每次reshard只能寫一個目的節點,因此以上命令需要執行三次(--cluster-to對應不同的目的節點)。
#--cluster-yes:不回顯需要遷移的slot,直接遷移。
src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-to 0dbea2fff1554a3bbca70d28b81911e60c5bee6d --cluster-slots 1024 --cluster-yes

#(3)下線(刪除)節點 主節點
src/redis-cli --cluster del-node 127.0.0.1:6389 353662f6868b187ad15bad9b7271b8f0848adf10

在這裡插入圖片描述

推薦學習:

以上就是範例詳解redis怎麼部署叢集的詳細內容,更多請關注TW511.COM其它相關文章!