web-dev-qa-db-ja.com

memcacheとワイルドカード

キー値にワイルドカードを使用してmemcacheをクリアする方法があるかどうか疑問に思っています。

つまり、キー「1234〜foo」と別の「1234〜foo〜bar」のキャッシュがあるとします。

Clear( "1234 *")のようなものを使用してキャッシュをクリアし、上から両方をクリアする方法はありますか?

それが理にかなっていることを願っています。

ありがとう。

30
GivP

いいえ、これを行うための直接的な簡単な方法はありません。 [〜#〜] faq [〜#〜] はこれに対処し、一種の回避策を提供します。

名前空間による削除

Memcachedは、ワイルドカードの削除または名前空間による削除(名前空間がないため)をサポートしていませんが、これをシミュレートするために使用できるいくつかのトリックがあります。ただし、me​​mcachedサーバーへの追加のトリップが必要です。

PHPで、fooという名前空間を使用する例:

$ns_key = $memcache->get("foo_namespace_key");
// if not set, initialize it
if($ns_key===false) {
    $ns_key=Rand(1, 10000);
    $memcache->set("foo_namespace_key", $ns_key);
}
// cleverly use the ns_key
$my_key = "foo_".$ns_key."_12345";
$my_val = $memcache->get($my_key);

//To clear the namespace do:
$memcache->increment("foo_namespace_key");
49
Eric Petroelje

Eric Petroeljeによる名前空間ソリューションに関するメモ:

Memcachedが名前空間キーを削除するタイミングがわからないことを忘れないでください。 Memcacheは名前空間キーを削除する可能性があり、新しいキーを設定しようとすると、1〜10000の確率で、同じインデックスキーが選択されます。つまり、「ダーティ」な結果が得られます。これはありそうにありませんが、最終的には安全ではありません。

同じ問題は、PoulVernonによる解決策にもあります。

安全な解決策は、「ポインタキー」/「名前空間キー」に信頼できるストレージ(ディスクなど)を使用することです。

6
ksvendsen

PHPのこの関数はどうですか?

function deleteKeysByIndex($search) {
    $m = new Memcached();
    $m->addServer('localhost', 11211);
    $keys = $m->getAllKeys();
    foreach ($keys as $index => $key) {
        if (strpos($key,$search) !== false) {
            $m->delete($key);
        } else {
            unset($keys[$index]);
        }
    }

    // returns an array of keys which were deleted
    return $keys;
}

$ prefixで始まるキーを削除し、削除されたすべてのキーのリストを返します。私はこれを共有サーバー上の30,000以上のキーで実行しましたが、非常に高速でした。おそらく1秒未満でした。

2
billynoah

「1234」のmemcacheエントリを作成し、その中に関連するキーの配列を格納します。削除ルーチンで、これらのキーを読み取り、繰り返して削除します。

0
Paul Vernon