共計 12198 個字符,預計需要花費 31 分鐘才能閱讀完成。
這篇文章主要介紹“redis 如何部署集群”,在日常操作中,相信很多人在 redis 如何部署集群問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”redis 如何部署集群”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!
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 
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、哨兵的工作方式
哨兵架構下 client 端第一次從哨兵找出 redis 的主節點,后續就直接訪問 redis 的主節點,當 redis 的主節點發生變化,哨兵會第一時間感知到,并且將新的 redis 主節點通知給 client 端。
Sentinel 會定時的對自己監控的 master 執行 info 命令,獲取最新的主從關系,還會定時的給所有的 redis 節點發送 ping 心跳檢測命令,如果檢測到某個 master 無法響應了,就會在給其他 Sentinel 發送消息,主觀認為該 master 宕機,如果 Sentinel 集群認同該 master 下線的人數達到一個值,那么大家統一意見,下線該 master。
下線之前需要做的是找 Sentinel 集群中的某一個來執行下線操作,這個步驟叫領導者選舉,選出來以后會從該 master 所有的 slave 節點中挑一個合適的作為新的 master,并讓其他 slave 重新同步新的 master
若沒有足夠數量的 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
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
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
# 關閉保護模式
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
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
# 這里因該是在選舉 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 如何部署集群”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!