选库说明 et ┌──────────────┬───────────────────┬────────────────────────────────────┐ │ 组件 │ 包名 │ 说明 │ ├──────────────┼───────────────────┼────────────────────────────────────┤ │ Redis 连接池 │ hyperf/redis │ 官方协程安全底层 phpredis 扩展 │ ├──────────────┼───────────────────┼────────────────────────────────────┤ │ 缓存注解 │ hyperf/cache │ 官方Cacheable 等注解驱动 │ ├──────────────┼───────────────────┼────────────────────────────────────┤ │ 分布式锁 │ hyperf/cache 内置 │ 基于 Redis SET NX EX │ └──────────────┴───────────────────┴────────────────────────────────────┘ 阿里云 Redis现品牌名 Tair完全兼容 Redis 协议直接用 hyperf/redis 即可无需额外 SDK。 --- 一、阿里云 Tair 控制台配置1. 白名单 Tair 控制台 → 数据安全 → 白名单设置 - 内网访问填 ECS 内网 IP 或 VPC 网段如172.16.0.0/12 - ECS 与 Tair 必须同 VPC、同地域才能走内网延迟1ms2. 获取连接信息 Tair 控制台 → 实例详情 → 连接信息 - 内网地址r-xxxx.redis.rds.aliyuncs.com:6379标准版/哨兵版 - 集群版直连地址r-xxxx.redis.rds.aliyuncs.com:6379代理模式或各分片直连地址3. 实例类型对应连接方式 ┌───────────────────────┬────────────────────────┬─────────────────────┐ │ 实例类型 │ 连接方式 │ Hyperf 配置 │ ├───────────────────────┼────────────────────────┼─────────────────────┤ │ 标准版单节点/主从 │ 单节点连接 │ host/port │ ├───────────────────────┼────────────────────────┼─────────────────────┤ │ 集群版代理模式 │ 单节点连接透明代理 │ host/port同标准版 │ ├───────────────────────┼────────────────────────┼─────────────────────┤ │ 集群版直连模式 │ Redis Cluster 协议 │ cluster 配置 │ ├───────────────────────┼────────────────────────┼─────────────────────┤ │ 哨兵版 │ Sentinel 协议 │ sentinel 配置 │ └───────────────────────┴────────────────────────┴─────────────────────┘ ▎ 生产环境推荐集群版代理模式对应用透明配置最简单。 --- 二、安装依赖composerrequire hyperf/rediscomposerrequire hyperf/cache 确认 PHP 已安装 phpredis 扩展 php-m|grepredis# 或 Swoole 环境php--riredis --- 三、配置文件 config/autoload/redis.php?php declare(strict_types1);return[//标准版 / 集群版代理模式最常用default[hostenv(REDIS_HOST,127.0.0.1),authenv(REDIS_AUTH, null), // 阿里云格式账号:密码 或 直接密码port(int)env(REDIS_PORT,6379),db(int)env(REDIS_DB,0),timeout2.0,reservednull,retry_interval100,read_timeout2.0,pool[min_connections5,max_connections50,connect_timeout3.0,wait_timeout3.0,heartbeat30, // 防止阿里云 RDS 空闲断连max_idle_time60.0,],options[// 开启 SSL/TLS合规场景 //\Redis::OPT_SERIALIZER\Redis::SERIALIZER_NONE,],], //集群版直连模式cluster[cluster[enabletrue,namenull,seeds[env(REDIS_CLUSTER_NODE_1,127.0.0.1:7000), env(REDIS_CLUSTER_NODE_2,127.0.0.1:7001), env(REDIS_CLUSTER_NODE_3,127.0.0.1:7002),],read_timeout2.0,timeout2.0,persistentfalse,authenv(REDIS_AUTH, null),],pool[min_connections5,max_connections50,connect_timeout3.0,wait_timeout3.0,heartbeat30,max_idle_time60.0,],], //哨兵模式sentinel[sentinel[enabletrue,master_nameenv(REDIS_SENTINEL_MASTER,mymaster),nodes[env(REDIS_SENTINEL_NODE_1,127.0.0.1:26379), env(REDIS_SENTINEL_NODE_2,127.0.0.1:26380), env(REDIS_SENTINEL_NODE_3,127.0.0.1:26381),],persistentfalse,read_timeout2.0,timeout2.0,authenv(REDIS_AUTH, null),db0,],pool[min_connections5,max_connections50,connect_timeout3.0,wait_timeout3.0,heartbeat30,max_idle_time60.0,],],];.env# 标准版 / 集群版代理模式REDIS_HOSTr-xxxx.redis.rds.aliyuncs.comREDIS_PORT6379REDIS_AUTHyourpassword# 免账号认证直接填密码# REDIS_AUTHuser:password # 账号认证格式 账号:密码# 集群版直连REDIS_CLUSTER_NODE_1r-xxxx-db-0.redis.rds.aliyuncs.com:6379REDIS_CLUSTER_NODE_2r-xxxx-db-1.redis.rds.aliyuncs.com:6379REDIS_CLUSTER_NODE_3r-xxxx-db-2.redis.rds.aliyuncs.com:6379 --- 四、开启 SSL/TLS合规场景 阿里云 Tair 支持 SSL 加密需在控制台开启后下载 CA 证书。 // config/autoload/redis.php 的 options 中添加options[\Redis::OPT_SERIALIZER\Redis::SERIALIZER_NONE,], // 连接时通过host前缀指定 TLShosttls://r-xxxx.redis.rds.aliyuncs.com,port6380, // TLS 端口通常为6380或通过 context 传入证书options[stream[ssltrue,cafileBASE_PATH./storage/certs/tair-ca.pem,verify_peertrue,verify_peer_namefalse,],], --- 五、缓存配置 config/autoload/cache.php?phpreturn[default[driverHyperf\Cache\Driver\RedisDriver::class,packerHyperf\Codec\Packer\PhpSerializerPacker::class,prefixapp:cache:,skip_cache_results[],],];--- 六、实际使用示例6.1直接操作 Redis?php declare(strict_types1);namespace App\Service;use Hyperf\Redis\Redis;use Hyperf\Di\Annotation\Inject;class TokenService{#[Inject]private Redis$redis;// 存 Token2小时过期 publicfunctionsaveToken(int$userId, string$token): void{$keytoken:user:{$userId};$this-redis-setex($key,7200,$token);}// 验证 Token publicfunctionverifyToken(int$userId, string$token): bool{$keytoken:user:{$userId};return$this-redis-get($key)$token;}// 原子计数限流 publicfunctionrateLimit(string$ip, int$limit100): bool{$keyrate:{$ip}:.date(YmdHi);$count$this-redis-incr($key);if($count1){$this-redis-expire($key,60);}return$count$limit;}// 指定连接池多实例场景 publicfunctionuseCluster(): void{$redismake(Redis::class,[poolcluster]);$redis-set(key,value);}}6.2缓存注解推荐?php declare(strict_types1);namespace App\Service;use Hyperf\Cache\Annotation\Cacheable;use Hyperf\Cache\Annotation\CacheEvict;use Hyperf\Cache\Annotation\CachePut;class UserService{// 自动缓存TTL 3600skeyuser:info:#{id}#[Cacheable(prefix: user:info, ttl: 3600, value: #{id})]publicfunctiongetUserInfo(int$id): array{// 只有缓存未命中时才执行returnUser::find($id)-toArray();}// 更新时同步刷新缓存#[CachePut(prefix: user:info, ttl: 3600, value: #{user.id})]publicfunctionupdateUser(User$user): array{$user-save();return$user-toArray();}// 删除缓存#[CacheEvict(prefix: user:info, value: #{id})]publicfunctiondeleteUser(int$id): void{User::destroy($id);}}6.3分布式锁?php declare(strict_types1);namespace App\Service;use Hyperf\Redis\Redis;use Hyperf\Di\Annotation\Inject;class OrderService{#[Inject]private Redis$redis;publicfunctioncreateOrder(int$userId, array$data): array{$lockKeylock:order:user:{$userId};$lockValuniqid(,true);$ttl10;// 锁最多持有 10s // SET NX EX 原子加锁$locked$this-redis-set($lockKey,$lockVal,[NX,EX$ttl]);if(!$locked){throw new\RuntimeException(操作频繁请稍后重试);}try{// 业务逻辑return$this-doCreateOrder($userId,$data);}finally{// Lua 脚本原子释放锁防误删$scriptLUAifredis.call(get, KEYS[1])ARGV[1]thenreturnredis.call(del, KEYS[1])endreturn0LUA;$this-redis-eval($script,[$lockKey,$lockVal],1);}}privatefunctiondoCreateOrder(int$userId, array$data): array{// 实际下单逻辑...return[];}}6.4Pipeline 批量操作高性能写入 publicfunctionbatchSet(array$items): void{$this-redis-pipeline(function($pipe)use($items){foreach($itemsas$key$value){$pipe-setex(item:{$key},3600, serialize($value));}});}--- 七、连接池关键参数说明 heartbeat30阿里云 Tair 默认空闲超时300秒比 RDS 短很多连接池里的空闲连接超时后会被服务端断开下次使用报 Connection refused。heartbeat 设30秒定期保活完全规避这个问题。 max_connections50单个 Worker 进程的连接池上限。总连接数max_connections × Worker进程数不能超过 Tair 实例的最大连接数控制台可查。 --- 八、常见坑 ┌────────────────────────────────────┬───────────────────────────────┬────────────────────────────────────────────┐ │ 问题 │ 原因 │ 解决 │ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │ Connection refused │ 白名单未加 ECS IP │ 控制台加白名单 │ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │ WRONGPASS invalid │ 密码格式错误 │ 免账号认证直接填密码账号认证填 │ │ username-password pair │ │ user:password │ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │ 空闲连接断开 │ Tair 300s 超时 │ heartbeat30│ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │ 集群模式 MOVED 错误 │ 用了单节点连接访问集群直连 │ 改用 cluster 配置或换代理模式 │ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │ 缓存注解不生效 │ 类内部调用$this-method() │ 注解基于 AOP 代理必须通过容器调用 │ ├────────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────┤ │eval在集群模式报错 │ Lua 脚本跨 slot │ 所有 key 用{}强制同 slot如{user}:lock │ └────────────────────────────────────┴───────────────────────────────┴────────────────────────────────────────────┘ --- 九、生产检查清单 - 使用 Tair 内网地址不开外网端口 - 白名单只填 ECS 内网 IP 或 VPC 网段 - heartbeat 设置为30- max_connections × Worker数 ≤ Tair 实例最大连接数 ×0.8- 生产环境开启 Tair 自动备份 - 金融/合规场景开启 SSL/TLS 加密 - 缓存 key 统一加业务前缀避免 key 冲突 --- 核心链路hyperf/redis连接池 hyperf/cache注解缓存 Lua 脚本分布式锁。阿里云 Tair 完全兼容 Redis 协议不需要额外 SDK重点在白名单、密码格式和 heartbeat 保活三个配置。