Memcachedは優れたスケーラブルなキャッシュレイヤーですが、タグを管理できないという大きな問題が1つあります(私にとって)。また、タグはグループの無効化に非常に役立ちます。
私はいくつかの調査を行い、いくつかの解決策について知っています。
- Memcacheタグフォークhttp://code.google.com/p/memcached-tag/
- タグをエミュレートするコードの実装(標準のphpライブラリを使用していくつかのmemcacheキーを無効にする最良の方法を参照してください)
私のお気に入りのソリューションの1つは名前空間であり、このソリューションはmemcachedwikiで説明されています。
しかし、なぜ名前空間をキーキャッシュに統合するのかわかりませんか?
名前空間のトリックについて私が理解したことから、キーを生成するには、(キャッシュ上の)名前空間の値を取得する必要があります。そして、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のような別のキャッシュレイヤーを探していません