Redis集群实现方式
✅ 一、什么是 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 分布式解决方案。