Redis 分片集群搭建與故障轉(zhuǎn)移實戰(zhàn)指南(推薦)
1 搭建分片集群
主從和哨兵可以解決高可用、高并發(fā)讀的問題。但是依然有兩個問題沒有解決:
- 海量數(shù)據(jù)存儲問題
- 高并發(fā)寫的問題
使用分片集群可以解決上述問題,如圖:

分片集群特征:
- 集群中有多個 master,每個 master 保存不同數(shù)據(jù)
- 每個 master 都可以有多個 slave 節(jié)點
- master 之間通過 ping 監(jiān)測彼此健康狀態(tài)
- 客戶端請求可以訪問集群任意節(jié)點,最終都會被轉(zhuǎn)發(fā)到正確節(jié)點
1.1 集群結(jié)構(gòu)
分片集群需要的節(jié)點數(shù)量較多,這里我們搭建一個最小的分片集群,包含 3 個 master 節(jié)點,每個 master 包含一個 slave 節(jié)點。
這里我們會在同一臺虛擬機(jī)中開啟 6 個 redis 實例,模擬分片集群,信息如下:
| IP | PORT | 角色 |
|---|---|---|
| 172.31.76.134 | 7001 | master |
| 172.31.76.134 | 7002 | master |
| 172.31.76.134 | 7003 | master |
| 172.31.76.134 | 8001 | slave |
| 172.31.76.134 | 8002 | slave |
| 172.31.76.134 | 8003 | slave |
1.2 準(zhǔn)備實例和配置
這里不在 /tmp 目錄下也可以,建議在 home/用戶名/ 目錄下創(chuàng)建一個新的目錄代替 /tmp ,例如我是在 home/horizon/ 目錄下新建了 redis-cluster-test 目錄,所以我接下來的操作都是在 home/horizon/redis-cluster-test 中進(jìn)行的,在下面涉及到 /tmp 的配置或操作都需要先修改為 /redis-cluster-test 再操作。
刪除之前的 7001、7002、7003 這幾個目錄,重新創(chuàng)建出 7001、7002、7003、8001、8002、8003 目錄:
# 進(jìn)入/redis-cluster-test目錄 cd /redis-cluster-test # 刪除舊的,避免配置干擾 rm -rf 7001 7002 7003 # 創(chuàng)建目錄 mkdir 7001 7002 7003 8001 8002 8003
在 /redis-cluster-test 下準(zhǔn)備一個新的 redis.conf 文件,內(nèi)容如下:
port 6379 # 開啟集群功能 cluster-enabled yes # 集群的配置文件名稱,不需要我們創(chuàng)建,由redis自己維護(hù) cluster-config-file /redis-cluster-test/6379/nodes.conf # 節(jié)點心跳失敗的超時時間 cluster-node-timeout 5000 # 持久化文件存放目錄 dir /redis-cluster-test/6379 # 綁定地址 bind 0.0.0.0 # 讓redis后臺運(yùn)行 daemonize yes # 注冊的實例ip replica-announce-ip 192.168.150.101 # 保護(hù)模式 protected-mode no # 數(shù)據(jù)庫數(shù)量 databases 1 # 日志 logfile /redis-cluster-test/6379/run.log
將這個文件拷貝到每個目錄下:
# 進(jìn)入/tmp目錄 cd /tmp # 執(zhí)行拷貝 echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
修改每個目錄下的 redis.conf,將其中的 6379 修改為與所在目錄一致:
# 進(jìn)入/tmp目錄
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf1.3 啟動
因為已經(jīng)配置了后臺啟動模式,所以可以直接啟動服務(wù):
# 進(jìn)入/tmp目錄
cd /tmp
# 一鍵啟動所有服務(wù)
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf通過 ps 查看狀態(tài):
ps -ef | grep redis
發(fā)現(xiàn)服務(wù)都已經(jīng)正常啟動:

如果要關(guān)閉所有進(jìn)程,可以執(zhí)行命令:
ps -ef | grep redis | awk '{print $2}' | xargs kill或者(推薦這種方式):
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown1.4 創(chuàng)建集群
雖然服務(wù)啟動了,但是目前每個服務(wù)之間都是獨(dú)立的,沒有任何關(guān)聯(lián)。
我們需要執(zhí)行命令來創(chuàng)建集群,在 Redis5.0 之前創(chuàng)建集群比較麻煩,5.0 之后集群管理命令都集成到了 redis-cli 中。
我們使用的是 5.0 之后的版本,集群管理以及集成到了 redis-cli 中,格式如下:
redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
命令說明:
- redis-cli --cluster 或者 ./redis-trib.rb :代表集群操作命令
- create :代表是創(chuàng)建集群
- --replicas 1 或者 --cluster-replicas 1 :指定集群中每個 master 的副本個數(shù)為 1,此時“節(jié)點總數(shù) ÷ (replicas + 1) ”得到的就是 master 的數(shù)量。因此節(jié)點列表中的前 n 個就是 master,其它節(jié)點都是 slave 節(jié)點,隨機(jī)分配到不同 master
運(yùn)行后的樣子:

這里輸入 yes,則集群開始創(chuàng)建:

通過命令可以查看集群狀態(tài):
redis-cli -p 7001 cluster nodes

1.5 測試
嘗試連接 7001 節(jié)點,存儲一個數(shù)據(jù):
# 連接 redis-cli -c -p 7001 # 存儲數(shù)據(jù) set num 123 # 讀取數(shù)據(jù) get num # 再次存儲 set a 1

2 散列插槽
2.1 插槽原理
Redis 會把每一個 master 節(jié)點映射到 0~16383 共 16384 個插槽(hash slot)上,查看集群信息時就能看到:

數(shù)據(jù) key 不是與節(jié)點綁定,而是與插槽綁定。redis 會根據(jù) key 的有效部分計算插槽值,分兩種情況:
- key 中包含“{}”,且“{}”中至少包含 1 個字符,“{}” 中的部分是有效部分
- key 中不包含“{}”,整個 key 都是有效部分
例如:key 是 num,那么就根據(jù) num 計算,如果 key 是 {itcast}num,則根據(jù) itcast 計算。計算方式是利用 CRC16 算法得到一個 hash 值,然后對 16384 取余,得到的結(jié)果就是 slot 值。

如圖,在 7001 這個節(jié)點執(zhí)行 set a 1 時,對 a 做 hash 運(yùn)算,對 16384 取余,得到的結(jié)果是 15495,因此要存儲到 7003 節(jié)點。
到了 7003 后,執(zhí)行 get num 時,對 num 做 hash 運(yùn)算,對 16384 取余,得到的結(jié)果是 2765,因此需要切換到 7001 節(jié)點。
Redis 如何判斷某個 key 應(yīng)該在哪個實例?
- 將 16384 個插槽分配到不同的實例
- 根據(jù) key 的有效部分計算哈希值,對 16384 取余
- 余數(shù)作為插槽,尋找插槽所在實例即可
如何將同一類數(shù)據(jù)固定的保存在同一個 Redis 實例?
- 這一類數(shù)據(jù)使用相同的有效部分,例如 key 都以 {typeId} 為前綴

3 集群伸縮
redis-cli --cluster 提供了很多操作集群的命令,可以通過下面方式查看:

比如,添加節(jié)點的命令:

3.1 需求分析
需求:向集群中添加一個新的 master 節(jié)點,并向其中存儲 num = 10
- 啟動一個新的 redis 實例,端口為 7004
- 添加 7004 到之前的集群,并作為一個 master 節(jié)點
- 給 7004 節(jié)點分配插槽,使得 num 這個 key 可以存儲到 7004 實例
這里需要兩個新的功能:
- 添加一個節(jié)點到集群中
- 將部分插槽分配到新插槽
3.2 創(chuàng)建新的 redis 實例
創(chuàng)建一個文件夾:
mkdir 7004
拷貝配置文件:
cp redis.conf /7004
修改配置文件:
sed /s/6379/7004/g 7004/redis.conf
啟動:
redis-server 7004/redis.conf
3.3 添加新節(jié)點到 redis
添加節(jié)點的語法如下:

執(zhí)行命令:
redis-cli --cluster add-node 172.31.76.134:7004 172.31.76.134:7001
通過命令查看集群狀態(tài):
redis-cli -p 7001 cluster nodes
如圖,7004 加入了集群,并且默認(rèn)是一個 master 節(jié)點:

但是,可以看到 7004 節(jié)點的插槽數(shù)量為 0,因此沒有任何數(shù)據(jù)可以存儲到 7004 上。
3.4 轉(zhuǎn)移插槽
我們要將 num 存儲到 7004 節(jié)點,因此需要先看看 num 的插槽是多少:

如上圖所示,num 的插槽為 2765。
我們可以將 0~3000 的插槽從 7001 轉(zhuǎn)移到 7004,具體命令如下:
建立連接:
redis-cli --cluster reshard 172.31.76.134:7001
得到下面的反饋:
詢問要移動多少個插槽,我們計劃是3000個:

新的問題來了:

哪個 node 來接收這些插槽??
顯然是 7004,那么 7004 節(jié)點的 id 是多少呢?

復(fù)制這個 id,然后拷貝到剛才的控制臺后:

這里詢問,你的插槽是從哪里移動過來的?
- all:代表全部,也就是三個節(jié)點各轉(zhuǎn)移一部分
- 具體的 id:目標(biāo)節(jié)點的 id
- done:沒有了
這里我們要從 7001 獲取,因此填寫 7001 的 id。

填完后,點擊done,這樣插槽轉(zhuǎn)移就準(zhǔn)備好了。

確認(rèn)要轉(zhuǎn)移嗎?輸入 yes。
然后,通過命令查看結(jié)果,可以看到:

目的達(dá)成。
4 故障轉(zhuǎn)移
集群初始狀態(tài)是這樣的:

其中 7001、7002、7003 都是 master,我們計劃讓 7002 宕機(jī)。
4.1 自動故障轉(zhuǎn)移
當(dāng)集群中有一個 master 宕機(jī)會發(fā)生什么呢?
直接停止一個 redis 實例,例如 7002:
redis-cli -p 7002 shutdown
- 首先是該實例與其它實例失去連接
- 然后是疑似宕機(jī)
- 最后是確定下線,自動提升一個 slave 為新的 master
- 當(dāng) 7002 再次啟動,就會變?yōu)橐粋€ slave 節(jié)點了

4.2 手動故障轉(zhuǎn)移
利用 cluster failover 命令可以手動讓集群中的某個 master 宕機(jī),切換到執(zhí)行 cluster failover 命令的這個 slave 節(jié)點,實現(xiàn)無感知的數(shù)據(jù)遷移。其流程如下:

這種 failover 命令可以指定三種模式:
- 缺省:默認(rèn)的流程,如圖 1~6 步
- force:省略了對 offset 的一致性校驗
- takeover:直接執(zhí)行第 5 步,忽略數(shù)據(jù)一致性、忽略 master 狀態(tài)和其它 master 的意見
案例需求:
在 7002 這個 slave 節(jié)點執(zhí)行手動故障轉(zhuǎn)移,重新奪回 master 地位
步驟如下:
- 利用 redis-cli 連接 7002 這個節(jié)點
- 執(zhí)行 cluster failover 命令
如圖:

效果:

5 RedisTemplate訪問分片集群
RedisTemplate 底層同樣基于 lettuce 實現(xiàn)了分片集群的支持,而使用的步驟與哨兵模式基本一致:
- 引入 redis 的 starter 依賴
- 配置分片集群地址
- 配置讀寫分離
與哨兵模式相比,其中只有分片集群的配置方式略有差異,如下:
spring:
redis:
cluster:
nodes:
- 172.31.76.134:7001
- 172.31.76.134:7002
- 172.31.76.134:7003
- 172.31.76.134:8001
- 172.31.76.134:8002
- 172.31.76.134:8003到此這篇關(guān)于Redis 分片集群搭建與故障轉(zhuǎn)移實戰(zhàn)指南(推薦)的文章就介紹到這了,更多相關(guān)Redis 分片集群搭建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis與RabbitMQ的區(qū)別對比和結(jié)合應(yīng)用
RabbitMQ和Redis是兩種流行的消息隊列(Message Queue)和緩存系統(tǒng),在應(yīng)用程序開發(fā)中起著不同的角色和功能,Redis憑借內(nèi)存存儲和豐富數(shù)據(jù)結(jié)構(gòu)實現(xiàn)高速緩存和分布式鎖,RabbitMQ通過消息隊列實現(xiàn)系統(tǒng)解耦和異步處理,二者結(jié)合可應(yīng)對電商秒殺等高并發(fā)場景2025-10-10
Redis 緩存實現(xiàn)存儲和讀取歷史搜索關(guān)鍵字的操作方法
這篇文章主要介紹了Redis 緩存實現(xiàn)存儲和讀取歷史搜索關(guān)鍵字,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12

