2

Redis と APCu の両方を使用する PHP タグ付きキャッシュの実装をセットアップしています。APC はキーと値のストアであるため、キーとタグの関連付けに Redis を使用し、APC 上の各 Web サーバーと同期します。

私の現在の質問は Redis のみに関するものです。おそらく実装はご存知でしょうが、明確にするために、キーにはタグを関連付けることができます。後で、キャッシュされたキーをいくつかのタグで削除できます。キーは多く、タグはそれほど多くなく、キーとタグの間には n 対 n の関係があります。

set(key, value, tags)で構成されています:

SET key value
foreach tag in tags
    SADD tag key

設定後にタグを取得または変更する必要がないため、タグとキーの関係を維持するだけで済みます。

deleteByTag(tags)

keys = SUNION tag1 tag2 tag3...
DEL key1 key2 key2...

作業を高速化するために、SCRIPT LOAD と EVALSHA を呼び出す 2 つの単純な lua スクリプトを作成しました。

Luaセットスクリプト:

redis.call('set', KEYS[1], KEYS[2])
for _, tag in pairs(ARGV) do
    redis.call('sadd', tag, KEYS[1])
end

と呼ばれる

EVALSHA setHash 2 key value tag1 tag2 tag3...

私が問題を抱えているdeleteByTagスクリプトは次のようになります。

redis.call('del', unpack(redis.call('sunion', unpack(ARGV))))
redis.call('del', unpack(ARGV))

と呼ばれる

EVALSHA deleteByTagHash 0 tag1 tag2 tag3...

redis.call('sunion', unpack(ARGV))多くのキーを返す場合を除いて、すべて問題ありません。Lua では、メソッドが持つことができる引数の数に厳しい制限があるようです。私の環境では8000です。
タグでキーをクリアする方法があるかどうかを知りたいのですが、回避します:

  • (1) サーバーへのラウンドトリップとクライアントへのキー転送
  • (2) for-each on キー。この修正されたスクリプトで試してみましたが、(1) よりも遅いです

十分に速く動作していない (2) は次のとおりです。

for _, key in pairs(redis.call('sunion', unpack(ARGV))) do
    redis.call('del', key)
end
redis.call('del', unpack(ARGV))
4

2 に答える 2

3

同じ問題があり、このLua関数で解決しました:

local call_in_chunks = function (command, args)
    local step = 1000
    for i = 1, #args, step do
        redis.call(command, unpack(args, i, math.min(i + step - 1, #args)))
    end
end

call_in_chunks('del', keys)
于 2016-10-10T13:37:00.853 に答える