Redis Cluster集群架构与数据分片原理
Redis Cluster是Redis官方提供的分布式集群方案,通过数据分片实现水平扩展。在数据库运维中,当单节点Redis的内存容量或吞吐量达到瓶颈时,Cluster模式将数据分布在多个节点上,每个节点负责部分数据子集。Cluster采用无中心架构,所有节点通过Gossip协议互相通信,不存在单点故障。
Redis Cluster使用16384个哈希槽(Hash Slot)进行数据分片。每个键通过CRC16算法计算哈希值后对16384取模,确定所属槽位。集群中的每个节点负责一部分槽位,例如3节点集群中节点A负责0-5460,节点B负责5461-10922,节点C负责10923-16383。
Key与槽位的映射关系可以通过hash tag控制。当键名中包含{…}时,仅大括号内的部分参与哈希计算,确保相关键分配到同一槽位,支持在同一节点上执行多键操作和事务。
# hash tag示例 - user相关的键都在同一槽位
SET user:{1001}:profile "alice"
SET user:{1001}:orders "order_list"
# 两个键的hash tag都是"1001",分配到同一槽位
Cluster集群搭建与节点配置
最小Cluster集群需要6个节点:3主3从。以下是基于Docker的搭建流程:
# 创建Docker网络
docker network create redis-cluster
# 启动6个Redis节点
for i in $(seq 1 6); do
docker run -d --name redis-$i --net redis-cluster \
-v redis-$i-data:/data \
redis:7 redis-server \
--port 6379 \
--cluster-enabled yes \
--cluster-config-file nodes.conf \
--cluster-node-timeout 5000 \
--appendonly yes \
--appendfsync everysec
done
# 创建集群(3主3从)
docker exec -it redis-1 redis-cli --cluster create \
redis-1:6379 redis-2:6379 redis-3:6379 \
redis-4:6379 redis-5:6379 redis-6:6379 \
--cluster-replicas 1
# 查看集群状态
docker exec -it redis-1 redis-cli -c cluster info
docker exec -it redis-1 redis-cli -c cluster nodes
cluster-enabled yes启用集群模式,cluster-node-timeout设置节点超时时间(毫秒),超过此时间无响应的节点被标记为PFAIL状态。cluster-replicas 1表示每个主节点配备1个从节点。
读写分离与故障转移机制
Redis Cluster的读写策略:默认情况下,读请求路由到键所在的主节点。通过READONLY命令可以让从节点处理读请求,实现读写分离。但需要注意,Redis的复制是异步的,从节点可能存在数据延迟,对一致性要求高的读操作仍应路由到主节点。
# 连接集群并启用从节点读
redis-cli -c -h redis-1 -p 6379
127.0.0.1:6379> READONLY
OK
127.0.0.1:6379> GET user:1001
# 如果该键不在当前节点,集群会返回MOVED重定向
故障转移是Cluster的高可用核心机制。当主节点宕机时,其从节点发起选举成为新主节点。选举流程:从节点检测到主节点超时后,向其他主节点发送投票请求,获得多数派投票后升级为主节点,接管原主节点的槽位。
# 手动故障转移(计划内切换)
redis-cli -c -h slave-node -p 6379 cluster failover
# 强制故障转移
redis-cli -c -h slave-node -p 6379 cluster failover TAKEOVER
# 查看集群槽位分布
redis-cli -c cluster slots
缓存穿透与布隆过滤器方案
缓存穿透是指大量请求查询不存在的数据,Redis中无缓存,请求穿透到数据库。布隆过滤器(Bloom Filter)在Redis层之前拦截对不存在数据的查询,通过概率数据结构判断数据是否可能存在。
# RedisBloom模块 - 添加布隆过滤器
# 需要安装RedisBloom模块
docker run -d --name redis-bloom -p 6380:6379 \
redislabs/rebloom:latest
# 创建布隆过滤器并添加元素
127.0.0.1:6380> BF.RESERVE user_exists 0.001 1000000
OK
127.0.0.1:6380> BF.ADD user_exists "user:1001"
(integer) 1
127.0.0.1:6380> BF.EXISTS user_exists "user:1001"
(integer) 1
127.0.0.1:6380> BF.EXISTS user_exists "user:9999"
(integer) 0
# Java集成示例
import io.rebloom.client.Client;
Client bloomClient = new Client("localhost", 6380);
bloomClient.createFilter("user_exists", 1000000, 0.001);
public User getUser(String userId) {
// 先查布隆过滤器
if (!bloomClient.exists("user_exists", "user:" + userId)) {
return null; // 数据一定不存在
}
// 查Redis缓存
String cached = redis.get("user:" + userId);
if (cached != null) {
return deserialize(cached);
}
// 查数据库
User user = db.findById(userId);
if (user != null) {
redis.setex("user:" + userId, 3600, serialize(user));
}
return user;
}
布隆过滤器的误判率(false positive rate)参数需要权衡:误判率越低,内存占用越大。0.001的误判率意味着每1000次查询最多1次误判,对于百万级数据集需要约1.7MB内存。
缓存雪崩与热点Key治理
缓存雪崩是指大量缓存同时过期,请求全部打到数据库导致数据库过载。解决方案是给缓存过期时间添加随机偏移,避免同时失效:
# Python实现 - 随机过期时间
import redis
import random
import json
r = redis.RedisCluster(host='redis-cluster', port=6379)
def cache_set(key, value, base_ttl=3600):
# 基础TTL + 随机偏移(300-600秒)
ttl = base_ttl + random.randint(300, 600)
r.setex(key, ttl, json.dumps(value))
def cache_get_or_load(key, loader_func, base_ttl=3600):
# 双重检查锁定模式
val = r.get(key)
if val is not None:
return json.loads(val)
# 加锁防止缓存击穿(大量并发同时加载同一key)
lock_key = f"lock:{key}"
acquired = r.set(lock_key, "1", nx=True, ex=10)
if not acquired:
# 等待其他线程加载缓存
time.sleep(0.1)
val = r.get(key)
if val is not None:
return json.loads(val)
return loader_func()
try:
val = loader_func()
cache_set(key, val, base_ttl)
return val
finally:
r.delete(lock_key)
热点Key问题是指某个Key的访问量远超其他Key,导致所在节点负载不均。Redis Cluster不支持在集群内自动均衡热点Key的读流量。解决方案包括:使用本地缓存(Caffeine/Guava)拦截热点读请求、在应用层将热点Key复制为多个副本(key:1, key:2…)分散到不同节点、使用读写分离将读流量分散到从节点。
Redis Cluster的运维监控需要关注以下指标:cluster_state(集群状态应为ok)、cluster_slots_assigned(已分配槽数应为16384)、cluster_slots_ok(正常槽数)、connected_clients(连接数)、used_memory(内存使用量)。通过Redis Exporter可以将这些指标接入Prometheus+Grafana监控体系,实现集群状态的实时可视化与告警。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rediscluster-ji-qun-bu-shu-yu-huan-cun-yi-zhi-xing-fang-an/