? 一、什么是 Redis 集群(Redis Cluster)
Redis 集群是 Redis 官方在 3.0 版本引入的分布式部署方案,它的目標是解決以下幾個問題:
-
單個 Redis 實例容量有限(最多只能使用一個服務器的內存)
-
單點故障(單個 Redis 服務掛掉就無法使用)
-
擴展性不足(性能受限于單機)
🔧 Redis Cluster 的三大核心機制:
機制 | 說明 |
---|---|
數據分片 | 使用 16384 個哈希槽(hash slots),所有數據根據 key 的哈希值分布到不同節點中 |
主從復制 | 每個主節點可配置多個從節點,做數據備份,提高可用性 |
自動故障轉移 | 主節點掛了,自動把從節點升級為主節點,無需人工干預 |
? 二、Redis 集群的部署方式(手把手教學)
我們以部署 6 個 Redis 實例(3 主 3 從)為例來講解:
📁 1. 準備 Redis 安裝文件
你可以先下載并解壓 Redis:
wget http://download.redis.io/releases/redis-6.2.6.tar.gz
tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6
make
📂 2. 創建多個 Redis 實例目錄
我們創建 6 個目錄,每個實例用不同端口:
mkdir -p ~/redis-cluster/7000
mkdir -p ~/redis-cluster/7001
mkdir -p ~/redis-cluster/7002
mkdir -p ~/redis-cluster/7003
mkdir -p ~/redis-cluster/7004
mkdir -p ~/redis-cluster/7005
🧾 3. 配置 redis.conf 文件
以 7000
為例配置一個 redis.conf(復制后修改端口即可):
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
dir /home/youruser/redis-cluster/7000
logfile "7000.log"
daemonize yes
每個實例都配置好自己的端口,節點配置文件名、日志名和工作目錄。
? 4. 啟動 Redis 實例
逐個啟動這 6 個 Redis 服務:
redis-server ~/redis-cluster/7000/redis.conf
redis-server ~/redis-cluster/7001/redis.conf
...
你可以使用 ps -ef | grep redis
或 netstat -anp | grep 700
來確認服務是否正常啟動。
🔗 5. 創建 Redis 集群
使用 redis-cli
創建集群,并設置主從結構(3主3從):
redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
含義是:
-
把前 3 個端口(7000~7002)作為主節點
-
后 3 個端口(7003~7005)作為各主節點的從節點
-
16384 個槽會被均分
集群創建成功后會提示你是否確認,輸入 yes
即可。
? 三、Redis 集群的運行機制
1. 數據是如何分片的?
-
Redis 把 key 的 CRC16 哈希值 對 16384 取模,確定它屬于哪個槽(slot)。
-
每個主節點管理一部分槽,例如:
7000 管理 0 ~ 5460 7001 管理 5461 ~ 10922 7002 管理 10923 ~ 16383
2. 節點之間如何通信?
-
所有節點通過 gossip 協議交換狀態信息。
-
每個節點都知道其他節點的位置和狀態。
-
使用兩個端口:如 7000 端口用于數據交互,7000+10000=17000 端口用于集群節點間通信。
3. 自動故障轉移
-
如果主節點宕機,其從節點在其他節點投票多數通過后,會自動升級為主節點。
-
故障恢復后重新加入集群。
? 四、Redis 集群的客戶端接入
1. 普通 redis-cli 無法處理集群請求(因為 key 可能在不同節點)
必須使用帶 --cluster
的命令,或者使用支持 Cluster 的客戶端。
2. Java 客戶端接入(Jedis 示例)
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("127.0.0.1", 7000));
nodes.add(new HostAndPort("127.0.0.1", 7001));
nodes.add(new HostAndPort("127.0.0.1", 7002));JedisCluster cluster = new JedisCluster(nodes);
cluster.set("name", "redis-cluster");
String value = cluster.get("name");
System.out.println(value);
? 五、注意事項和限制
限制 | 描述 |
---|---|
不支持事務(MULTI/EXEC)跨 slot 操作 | |
MGET/MSET 必須作用于同一 slot(可以用 {tag} 方式強制放入同一槽) | |
數據遷移時性能會波動 | |
客戶端必須支持 Redis Cluster 協議 |
? 六、總結(一句話回顧)
Redis Cluster 是一種去中心化的、基于數據分片和主從復制的高可用、高擴展性的 Redis 分布式解決方案。