【发布时间】:2012-06-09 06:22:26
【问题描述】:
Memcached 是一个很棒的可扩展缓存层,但它有一个大问题(对我来说)它无法管理标签。并且标签对于组失效非常有用。
我做了一些研究,我知道一些解决方案:
- Memcache 标签分叉http://code.google.com/p/memcached-tag/
- 模拟标签的代码实现(参考Best way to invalidate a number of memcache keys using standard php libraries?)
我最喜欢的解决方案之一是命名空间,此解决方案在 memcached wiki 上进行了说明。
但是我不明白为什么我们要在键缓存上集成命名空间?
据我了解关于命名空间的技巧是:要生成密钥,我们必须获取命名空间的值(在缓存上)。如果namespace->value 缓存条目被驱逐,我们就无法再计算获取缓存的好键...所以这个命名空间的缓存虚拟无效(我说虚拟是因为缓存仍然存在但我们无法再计算访问密钥)。
那么为什么我们不能简单地实现类似的东西:
tag1->[key1, key2, key5]
tag2->[key1, key3, key6]
key1->["value" => value1, "tags" => [tag1, tag2]]
key2->["value" => value2, "tags" => [tag1]]
key3->["value" => value3, "tags" => [tag3]]
etc...
有了这个实现,我又遇到了一个问题,如果tag1->[key1, key2, key5] 被驱逐,我们就不能再使 tag1 键失效。但随着
function load($cacheId) {
$cache = $memcache->get($cacheId);
if (is_array($cache)) {
$evicted = false;
// Check is no tags have been evicted
foreach ($cache["tags"] as $tagId) {
if (!$memcache->get($tagId) {
$evicted = true;
break;
}
}
// If no tags have been evicted we can return cache
if (!$evicted) {
return $cache
} else {
// Not mandatory
$memcache->delete($cacheId);
}
// Else return false
return false;
}
}
这是伪代码
如果所有这些标签都可用,我们肯定会返回缓存。
首先我们可以说它是“每次你需要获取缓存时,我们必须检查(/获取)X标签,然后检查数组”。但是对于命名空间,我们还必须检查(/get)命名空间来检索命名空间值,主要的区别是在一个数组下迭代...... 但我不认为键会有很多标签(我无法想象我的应用程序有超过 10 个标签/键),所以在大小为 10 的数组下迭代它的速度非常快..
所以我的问题是:有人已经考虑过这个实现了吗?限制是什么?我是不是忘记了什么?等等
或者我可能误解了命名空间的概念......
PS:我不是在寻找另一个缓存层,比如 memcached-tag 或 redis
【问题讨论】: