Redis Cluster 概述
Redis Cluster 是 Redis 官方提供的分散式解決方案,能夠自動將資料分片儲存於多個節點中,並提供高可用性與故障自動轉移功能。相較於單一 Redis 實例,Cluster 模式可以突破單機記憶體限制,同時透過主從複製確保資料安全。
主要特性
- 資料分片(Sharding):自動將資料分散到多個節點
- 高可用性:主節點故障時,從節點自動升級為主節點
- 線性擴展:可動態新增或移除節點
- 無中心架構:採用 Gossip 協定進行節點間通訊
叢集架構與分片原理
Redis Cluster 使用 Hash Slot 機制進行資料分片。整個叢集共有 16384 個 slot,每個 key 透過 CRC16 演算法計算後,對 16384 取模決定存放位置:
1
| HASH_SLOT = CRC16(key) mod 16384
|
最小叢集配置
建議至少使用 6 個節點:3 個主節點(Master)加上 3 個從節點(Slave),確保每個主節點都有對應的備援節點。
環境準備
節點規劃
| 節點角色 | IP 位址 | 連接埠 |
|---|
| Master 1 | 192.168.1.101 | 7001 |
| Master 2 | 192.168.1.102 | 7002 |
| Master 3 | 192.168.1.103 | 7003 |
| Slave 1 | 192.168.1.104 | 7004 |
| Slave 2 | 192.168.1.105 | 7005 |
| Slave 3 | 192.168.1.106 | 7006 |
系統需求
- Ubuntu 22.04 LTS
- 每個節點至少 2GB RAM
- 開放 Redis 連接埠及叢集匯流排連接埠(連接埠 + 10000)
Redis 安裝與設定
安裝 Redis
在所有節點上執行:
1
2
| sudo apt update
sudo apt install redis-server -y
|
設定檔調整
編輯 /etc/redis/redis.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| # 綁定 IP 位址(依據各節點實際 IP 調整)
bind 192.168.1.101
# 連接埠設定
port 7001
# 啟用叢集模式
cluster-enabled yes
# 叢集設定檔(由 Redis 自動管理)
cluster-config-file nodes-7001.conf
# 節點超時時間(毫秒)
cluster-node-timeout 5000
# 啟用 AOF 持久化
appendonly yes
appendfilename "appendonly-7001.aof"
# RDB 快照設定
dbfilename dump-7001.rdb
dir /var/lib/redis
# 關閉保護模式(僅限內網環境)
protected-mode no
# 設定密碼(建議設定)
requirepass your_redis_password
masterauth your_redis_password
# 記憶體上限
maxmemory 1gb
maxmemory-policy allkeys-lru
# 背景執行
daemonize yes
pidfile /var/run/redis/redis-server-7001.pid
# 日誌設定
logfile /var/log/redis/redis-server-7001.log
loglevel notice
|
防火牆設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 開放 Redis 連接埠
sudo ufw allow 7001/tcp
sudo ufw allow 7002/tcp
sudo ufw allow 7003/tcp
sudo ufw allow 7004/tcp
sudo ufw allow 7005/tcp
sudo ufw allow 7006/tcp
# 開放叢集匯流排連接埠
sudo ufw allow 17001/tcp
sudo ufw allow 17002/tcp
sudo ufw allow 17003/tcp
sudo ufw allow 17004/tcp
sudo ufw allow 17005/tcp
sudo ufw allow 17006/tcp
|
啟動 Redis
1
2
| sudo systemctl restart redis-server
sudo systemctl enable redis-server
|
建立叢集
確認所有節點都已啟動後,使用 redis-cli 建立叢集:
1
2
3
4
5
6
7
8
9
| redis-cli --cluster create \
192.168.1.101:7001 \
192.168.1.102:7002 \
192.168.1.103:7003 \
192.168.1.104:7004 \
192.168.1.105:7005 \
192.168.1.106:7006 \
--cluster-replicas 1 \
-a your_redis_password
|
執行後會自動分配 Hash Slot 並建立主從關係,輸入 yes 確認。
驗證叢集狀態
1
2
| redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password cluster info
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password cluster nodes
|
新增與移除節點
新增主節點
1
2
| redis-cli --cluster add-node 192.168.1.107:7007 192.168.1.101:7001 \
-a your_redis_password
|
新增從節點
1
2
3
| redis-cli --cluster add-node 192.168.1.108:7008 192.168.1.101:7001 \
--cluster-slave --cluster-master-id <master-node-id> \
-a your_redis_password
|
重新分配 Slot
1
| redis-cli --cluster reshard 192.168.1.101:7001 -a your_redis_password
|
移除節點
1
2
3
4
5
6
| # 先遷移 Slot(若為主節點)
redis-cli --cluster reshard 192.168.1.101:7001 -a your_redis_password
# 移除節點
redis-cli --cluster del-node 192.168.1.101:7001 <node-id> \
-a your_redis_password
|
故障轉移測試
手動觸發故障轉移
連接到從節點執行:
1
2
| redis-cli -c -h 192.168.1.104 -p 7004 -a your_redis_password
> CLUSTER FAILOVER
|
模擬主節點故障
1
2
3
4
5
| # 停止主節點
sudo systemctl stop redis-server
# 觀察叢集狀態(從其他節點)
redis-cli -c -h 192.168.1.102 -p 7002 -a your_redis_password cluster nodes
|
從節點會在 cluster-node-timeout 時間後自動升級為主節點。
應用程式連線
Python 範例(redis-py-cluster)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| from rediscluster import RedisCluster
startup_nodes = [
{"host": "192.168.1.101", "port": "7001"},
{"host": "192.168.1.102", "port": "7002"},
{"host": "192.168.1.103", "port": "7003"}
]
rc = RedisCluster(
startup_nodes=startup_nodes,
decode_responses=True,
password="your_redis_password"
)
rc.set("key", "value")
print(rc.get("key"))
|
Node.js 範例(ioredis)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| const Redis = require('ioredis');
const cluster = new Redis.Cluster([
{ host: '192.168.1.101', port: 7001 },
{ host: '192.168.1.102', port: 7002 },
{ host: '192.168.1.103', port: 7003 }
], {
redisOptions: {
password: 'your_redis_password'
}
});
cluster.set('key', 'value');
cluster.get('key').then(console.log);
|
監控與維護
常用監控指令
1
2
3
4
5
6
7
8
9
10
11
| # 叢集資訊
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password cluster info
# 節點列表
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password cluster nodes
# Slot 分配狀態
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password cluster slots
# 記憶體使用狀況
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password info memory
|
備份策略
建議同時啟用 RDB 快照與 AOF 日誌:
1
2
3
4
5
| # 手動觸發 RDB 備份
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password BGSAVE
# 手動重寫 AOF
redis-cli -c -h 192.168.1.101 -p 7001 -a your_redis_password BGREWRITEAOF
|
參考資料