hyperf 3.1 缓存注解默认不兼容 redis 集群,因原生 redisdriver 仅支持单节点;需显式配置集群驱动、使用 hash tag 确保 key 路由,并自定义 clusterredisdriver 绑定集群实例,否则将连接首个节点导致 crossslot 错误。

Hyperf 3.1 的缓存注解(如 #[Cacheable])默认不兼容 Redis 集群模式,因为其底层 RedisDriver 依赖单节点连接池,无法自动路由 key 到对应 slot。若强行将集群地址填入 redis.php 的单实例配置,只会连第一个节点,导致数据错乱或命令失败(如 CROSSSLOT 错误)。要让缓存注解真正适配 Redis 集群,必须替换驱动并确保整个链路支持 slot 分片逻辑。
必须使用官方 Cluster 驱动,而非手动拼接多个 Redis 实例
Hyperf 原生支持 Redis 官方 Cluster 协议(基于 16384 个 slot),但需显式启用:
- 在
config/autoload/redis.php中,为集群单独定义一个配置项(如'cluster'),不能复用 default 或其他单节点配置名 - 配置格式必须符合
phpredis或predis的集群要求:
– 使用'driver' => 'cluster'(phpredis)或'scheme' => 'redis'+ 多 host(predis)
– host 字段改为数组,例如'hosts' => ['redis://192.168.1.10:7000', 'redis://192.168.1.11:7001']
– 若用 phpredis,需确保扩展已开启redis.clusters配置并加载集群配置文件 - 连接池参数(
min_connections、max_connections)仍可设置,但 Swow 模式下需改用SwowHandler并禁用heartbeat和max_idle_time
缓存驱动必须绑定到集群配置,不能沿用默认 RedisDriver
默认的 Hyperf\Cache\Driver\RedisDriver 只接受单连接池名(如 'default'),不识别集群配置。需自定义驱动类:
- 新建类
ClusterRedisDriver,继承RedisDriver,重写构造方法,传入从RedisFactory获取的集群实例(非单节点) - 在
config/autoload/cache.php中,将default驱动指向该自定义类:'driver' => App\Cache\ClusterRedisDriver::class - 在
dependencies.php中绑定该驱动所需依赖,例如:$container->set(ClusterRedisDriver::class, function ($container) {<br> $redis = $container->get(RedisFactory::class)->get('cluster');<br> return new ClusterRedisDriver($redis, 3600);<br>});
缓存注解能用,但 key 路由和异常处理需额外注意
启用集群驱动后,#[Cacheable] 等注解即可生效,但以下细节影响稳定性:
- 所有 key 必须带大括号包裹 hash tag,例如
user:{123}:profile,否则集群无法保证同一业务数据落在同一节点,导致GET和SET跨 slot 失败 - 注解生成的 key 默认不含 hash tag,需在注解中手动添加,如:
#[Cacheable(prefix: "user:{", suffix: "}:profile")],使最终 key 为user:{123}:profile - 集群节点故障时,
phpredis会自动重试,但超时时间需调大:
在 redis 配置的options中设'timeout' => 3.0、'read_timeout' => 3.0,避免因短暂抖动触发降级 - 不支持
CacheInterface::getMultiple()批量获取跨 slot 的 key,注解批量操作(如#[CachePut]多参数)可能退化为多次单请求
不推荐用一致性哈希替代官方集群,除非有特殊扩容需求
虽然可通过 RedisArray 或 PredisCluster 实现一致性哈希,但与缓存注解深度耦合难度高:
- 注解底层调用的是
CacheInterface,而一致性哈希封装通常返回原生Redis或Predis\Client实例,无法直接塞进RedisDriver - 需完整重写
get/set/delete等方法,并手动处理空值、序列化、前缀等,失去注解开箱即用优势 - 平滑扩容价值在缓存场景有限——缓存本就允许部分 miss,而官方集群的 resharding 工具(
redis-cli --cluster reshard)已足够可控











