缓存失效
缓存失效是指移除所有与模型状态更改相关的缓存项的过程。最基本的失效类型是直接删除项目。但是,当主要资源的状态分散在多个缓存项中时,保持它们同步可能会很困难。
Symfony 缓存组件提供了两种机制来帮助解决这个问题
使用缓存标签
要从基于标签的失效中获益,你需要将适当的标签附加到每个缓存项。每个标签都是一个纯字符串标识符,你可以随时使用它来触发删除与此标签关联的所有项。
要将标签附加到缓存项,你需要使用由缓存项实现的 tag() 方法
1 2 3 4 5 6 7 8
$item = $cache->get('cache_key', function (ItemInterface $item): string {
// [...]
// add one or more tags
$item->tag('tag_1');
$item->tag(['tag_2', 'tag_3']);
return $cachedValue;
});
如果 $cache
实现了 TagAwareCacheInterface,你可以通过调用 invalidateTags() 使缓存项失效
1 2 3 4 5
// invalidate all items related to `tag_1` or `tag_3`
$cache->invalidateTags(['tag_1', 'tag_3']);
// if you know the cache key, you can also delete the item directly
$cache->delete('cache_key');
当跟踪缓存键变得困难时,使用标签失效非常有用。
支持标签的适配器
要存储标签,你需要使用 TagAwareAdapter 类包装缓存适配器,或者实现 TagAwareCacheInterface 及其 invalidateTags() 方法。
注意
当使用 Redis 后端时,请考虑使用 RedisTagAwareAdapter,它为此目的进行了优化。当使用文件系统时,同样考虑使用 FilesystemTagAwareAdapter。
TagAwareAdapter 类实现了瞬时失效(时间复杂度为 O(N)
,其中 N
是失效标签的数量)。它需要一个或两个缓存适配器:第一个必需的适配器用于存储缓存项;第二个可选的适配器用于存储标签及其失效版本号(概念上类似于它们最新的失效日期)。当仅使用一个适配器时,项和标签都存储在同一位置。通过使用两个适配器,你可以例如将一些大的缓存项存储在文件系统或数据库中,并将标签保存在 Redis 数据库中,以同步所有前端并进行非常快速的失效检查
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
$cache = new TagAwareAdapter(
// Adapter for cached items
new FilesystemAdapter(),
// Adapter for tags
new RedisAdapter('redis://127.0.0.1')
);
注意
TagAwareAdapter 实现了 PruneableInterface,通过调用其 prune() 方法(假设包装的适配器本身实现了 PruneableInterface),可以手动清理过期的缓存条目。