要在 Yii 2.0.48 中启用 Redis 缓存并获得高性能表现,必须避开默认的毫秒级过期陷阱、正确声明集群拓扑、复用依赖实例,否则缓存会频繁失效或直接报错;需通过 composer require 安装 yiisoft/yii2-redis,配置 redis 和 cache 组件时复用连接实例,修复 Cache.php 的毫秒溢出问题,使用 TagDependency 模拟标签,并在集群模式下正确设置 clusters 数组。

要在 Yii 2.0.48 中启用 Redis 缓存并获得高性能表现,必须避开默认的毫秒级过期陷阱、正确声明集群拓扑、复用依赖实例,否则缓存会频繁失效或直接报错。
安装与基础连接配置
执行 composer 命令安装扩展:composer require --prefer-dist yiisoft/yii2-redis。该命令会拉取兼容 Yii 2.0.48 的稳定版 redis 扩展(v2.0.14+),不支持更高主版本。
打开 common/config/main.php 或 config/web.php,在 'components' 数组中添加 'redis' 连接组件:
'redis' => [ 'class' => 'yii\redis\Connection', 'hostname' => '127.0.0.1', 'port' => 6379, 'database' => 0, 'password' => '', 'connectionTimeout' => 5, 'dataTimeout' => 5 ]
【database 必须为整数且不能是字符串】 若填 'database' => '0' 会导致连接失败但无明确报错,仅日志中出现 ERR invalid DB index。
启用 Redis 缓存组件
在同一配置文件中,将原 'cache' 组件替换为 Redis 实现:
'cache' => [ 'class' => 'yii\redis\Cache', 'redis' => ['class' => 'yii\redis\Connection'], 'keyPrefix' => 'app_v2_' ]
注意:此处 'redis' 不再重复写 hostname/port 等参数,而是复用上方已定义的 'redis' 组件名——Yii 2.0.48 会自动按名称查找并注入连接实例。
若仍沿用旧写法(把完整连接配置嵌套在 cache 下),会导致每次 get/set 都新建连接,严重拖慢性能。
修复毫秒级过期导致的负数崩溃
Yii 2.0.48 自带的 vendor/yiisoft/yii2-redis/Cache.php 第 133 行默认使用毫秒单位设置过期时间,而 Redis 命令 PX 要求值 ≤ 2147483647 毫秒(约 24.8 天)。超过则强转为 int 后溢出成负数,触发 ERR invalid expire time in SETEX 报错。
第一步:打开该文件,定位到 protected function setValue($key, $value, $expire) 方法
第二步:注释掉原 $expire = (int) ($expire * 1000); 和 SET 带 PX 的调用
第三步:替换为以下两行:
$expire = +$expire > 0 ? $expire : 0;
return (bool) $this->redis->executeCommand('SET', [$key, $value, 'EX', $expire]);
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
这一步改完后,所有 set('key', $val, 86400) 即表示缓存 1 天(秒级),不再需要手动 ×1000。
批量清除缓存:用 TagDependency 模拟标签
Yii 2.0.48 不支持原生 cache tag,必须用 TagDependency 手动模拟:
方法一:在控制器中临时创建(仅用于调试)
$tag = new \yii\caching\TagDependency(['tags' => 'user_list']);
Yii::$app->cache->set('users_1001', $data, 3600, $tag);
方法二:在 common/components/CacheHelper.php 中预定义复用实例(生产环境必需)
class CacheHelper { public static $userTag = null; public static function getUserTag() { if (self::$userTag === null) { self::$userTag = new \yii\caching\TagDependency(['tags' => 'user']); } return self::$userTag; } }
【必须复用同一实例,否则 invalidate 失效】 每次 new 都生成新标记键,TagDependency::invalidate(['user']) 将无法清除之前缓存的数据。
清除时调用:\yii\caching\TagDependency::invalidate(['user']); —— 注意传入的是字符串数组,且内容必须与构造时 tags 值完全一致。
Redis 集群配置(三节点最小可用)
若已部署 Redis 集群(至少 3 主 3 从),需显式启用集群模式:
修改 cache 组件配置:
'cache' => [ 'class' => 'yii\redis\Cache', 'redis' => [ 'class' => 'yii\redis\Connection', 'clusters' => [ '192.168.1.10:6379', '192.168.1.11:6379', '192.168.1.12:6379' ], ], 'keyPrefix' => 'cluster_app_' ]
【clusters 是数组,不是 cluster】 键名拼写错误(如写成 'cluster')会导致 Yii 忽略该配置,回退到单点连接,且无任何警告。
集群模式下,database 参数被忽略,所有操作自动路由到对应哈希槽所在节点;password 若存在,需确保每个节点密码一致,否则部分节点连接失败。


















