Ubuntu 22.04 Redis Cluster 叢集設定

Ubuntu 22.04 Redis Cluster Configuration

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 1192.168.1.1017001
Master 2192.168.1.1027002
Master 3192.168.1.1037003
Slave 1192.168.1.1047004
Slave 2192.168.1.1057005
Slave 3192.168.1.1067006

系統需求

  • 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

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy