You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Redis缓存场景下,如何按租户匹配清除指定缓存?

Laravel Redis缓存:清除指定租户的所有缓存键

问题原因

Laravel的Cache::forget()方法不支持通配符匹配,只能删除单个明确的缓存键,所以Cache::forget('*:'.$tenant)不会生效。下面提供三种可行的解决方案:


方案1:使用Redis SCAN命令批量删除(适配现有代码)

直接通过Redis实例遍历匹配租户的所有缓存键并删除,适合不想大规模修改现有缓存逻辑的场景。注意避免使用KEYS命令,它会在Redis数据量大时阻塞服务,改用SCAN渐进式遍历:

// 获取Redis缓存实例
$redis = Cache::getRedis();

// 初始化迭代器,遍历所有匹配 "*:$tenant" 的键
$iterator = null;
do {
    // 每次扫描1000个键,可根据实际调整COUNT值
    $result = $redis->scan($iterator, 'MATCH', "*:$tenant", 'COUNT', 1000);
    if (!empty($result[1])) {
        // 批量删除匹配到的键
        $redis->del(...$result[1]);
    }
} while ($iterator > 0);

方案2:用Redis哈希表组织租户缓存(结构更合理)

将单个租户的所有缓存数据存入同一个Redis哈希表中,删除时直接删除整个哈希表即可,操作更高效:

存储缓存

// 哈希表键名格式:tenant:{租户ID}:cache
$hashKey = "tenant:$tenant:cache";
$cacheKey = 'dep_count';

// 从哈希表获取缓存,不存在则计算并存入
$department_count = Cache::getRedis()->hGet($hashKey, $cacheKey);
if (!$department_count) {
    $department_count = Department::where('is_active', 'yes')
        ->where('tenantID', $tenant)
        ->count();
    // 设置哈希表字段,同时可以单独给字段设置过期时间(如果需要)
    Cache::getRedis()->hSet($hashKey, $cacheKey, $department_count);
    // 给整个哈希表设置过期时间
    Cache::getRedis()->expire($hashKey, 60 * 60 * 24);
}

清除租户所有缓存

$hashKey = "tenant:$tenant:cache";
Cache::getRedis()->del($hashKey);

方案3:使用Laravel缓存标签(最优雅的Laravel原生方案)

Laravel缓存标签支持批量清除同一标签下的所有缓存,Redis驱动原生支持该功能,代码更简洁:

存储带标签的缓存

$department_count = Cache::tags(["tenant:$tenant"])
    ->remember('dep_count', 60 * 60 * 24, function () use ($tenant) {
        return Department::where('is_active', 'yes')
            ->where('tenantID', $tenant)
            ->count();
    });

清除租户所有缓存

Cache::tags(["tenant:$tenant"])->flush();

内容的提问来源于stack exchange,提问作者Herman Ceaser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:24:26