Symfony标签缓存通过TagAwareCacheInterface实现按语义批量失效,需使用_redis_tag_aware等支持标签的适配器,写入时用ItemInterface::tag()绑定标签,失效时调用invalidateTags()清除指定标签的缓存项。

Symfony 标签缓存不是“给缓存加个标签”那么简单,而是通过 TagAwareCacheInterface 实现按语义批量失效的核心机制。它解决的是“一处更新、多处同步失效”的问题,比如改了一个商品,所有含该商品的列表页、详情页、推荐位缓存都要清掉——不用记一堆 key,只管 tag。
必须用支持标签的适配器
普通 cache.adapter.redis 或 cache.adapter.filesystem 不支持标签操作。得用带 _tag_aware 后缀的适配器:
-
cache.adapter.redis_tag_aware(推荐生产环境) cache.adapter.memcached_tag_aware-
cache.adapter.php_files_tag_aware(仅开发调试)
配置示例(config/packages/cache.yaml):
framework:
cache:
app: cache.adapter.redis_tag_aware
default_redis_provider: 'redis://localhost'
若用 Doctrine 结果缓存,也需指定 cache.adapter.redis_tag_aware,否则 invalidateTags() 会静默失败。
写缓存时绑定标签
标签必须在 get() 回调中,通过 ItemInterface::tag() 方法设置:
$product = $cache->get('product_456', function (ItemInterface $item) {
$item->tag(['products', 'product-456', 'category-electronics']);
$item->expiresAfter(7200);
return $this->productRepository->find(456);
});
注意:
– 一个缓存项可打多个标签,类型为 string 或 array
– tag() 必须在 set() 前调用,否则无效
– 标签名建议小写、无特殊字符(如避免空格、点号),便于跨后端兼容
按标签批量失效
调用 invalidateTags() 即可清除所有带指定标签的缓存项:
- 删单个资源相关缓存:
$cache->invalidateTags(['product-456']); - 删整个分类缓存:
$cache->invalidateTags(['category-electronics']); - 删多标签交集(AND 逻辑):
$cache->invalidateTags(['products', 'admin']);—— 注意:这是“同时含这两个标签”的项,不是 OR
返回 true 表示操作已提交(不保证底层全部删除完成),失败会抛异常。建议包裹 try/catch 并记录日志。
标签和键要配合使用
标签不能替代 key,二者分工明确:
-
key:定位唯一缓存项(如
product_456) -
tag:定义语义分组(如
products、user-789)
典型组合场景:
- 用户资料页缓存 → key:
profile_user_789,tag:user-789,profile - 用户订单列表 → key:
orders_user_789,tag:user-789,orders - 用户更新头像后 →
$cache->invalidateTags(['user-789']),自动清掉 profile 和 orders 缓存
这样既保持 key 的精确性,又获得 tag 的灵活性。











