Memcached是一个很好的可扩展缓存层,但它有一个大问题(对我来说)它无法管理标签。并且标签对于组失效非常有用。
我做了一些研究,我知道一些解决方案:
- Memcache 标签分叉http://code.google.com/p/memcached-tag/
- 模拟标签的代码实现(参考。使用标准 php 库使多个 memcache 键无效的最佳方法?)
我最喜欢的解决方案之一是命名空间,这个解决方案在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 的数组下迭代它的速度非常快..
所以我的问题是:有人已经考虑过这个实现了吗?限制是什么?我是不是忘记了什么?ETC
或者我可能误解了命名空间的概念......
PS:我不是在寻找像 memcached-tag 或 redis 这样的另一个缓存层