ホームページ  >  記事  >  バックエンド開発  >  PHP Redisでキーをバッチで削除する方法

PHP Redisでキーをバッチで削除する方法

藏色散人
藏色散人オリジナル
2020-10-07 00:38:095774ブラウズ

php Redis からキーをバッチで削除する方法: まずコマンド ウィンドウを開き、コマンド「redis-cli keys video* | xargs redis-cli del」を使用してキーをバッチで削除します。

PHP Redisでキーをバッチで削除する方法

redis はキーの一括削除機能を実装します

推奨: "PHP ビデオ チュートリアル "

keys

テスト環境で redis を使用する場合、キーをバッチで削除する必要があることがよくあります。ただし、redis にはバッチ削除コマンドがありませんが、キーを使用してキーをトラバースすることができます。実装

//批量删除以video开头的key
redis-cli keys video* | xargs redis-cli del

//以j,r开头,紧跟edis字符串的所有键
redis-cli keys [j,r]edis | xargs redis-cli del
注意:
    redis是单线程架构,如果redis包含了大量的键,执行keys命令可能会造成redis阻塞,所以一般建议不要在生产环境下使用keys命令。
    如果非要遍历键删除的话,可以在一下三种情况使用:
    (1)在一个不对外提供服务的Redis从节点上执行,这样不会阻塞到客户端的请求,但是会影响到主从复制。
    (2)如果确认键值总数确实比较少,可以执行该命令。
    (3)使用scan命令渐进式的遍历所有键,可以有效防止阻塞。

プログレッシブ トラバーサル

scan コマンド ドキュメント

Redis は、hgetall や hgetall などの問題を解決するために、ハッシュ タイプ、コレクション タイプ、および順序付けされたコレクションのスキャン トラバーサル コマンドを提供します。 smembers 、 zrange はブロッキングの問題を引き起こす可能性があります。対応するコマンドは hscan、sscan、zscan で、それらの使用法は基本的に scan と同様です。

注:
プログレッシブ トラバーサルは、keys コマンドで発生する可能性のあるブロック問題を効果的に解決できますが、スキャンは完全ではありません。スキャン中にキーの変更 (追加、削除) がある場合は、プロセス、変更)、
この場合、トラバーサル効果により次の問題が発生する可能性があります: 新しく追加されたキーが走査されない、重複したキーが走査されるなど。言い換えると、スキャンではすべてのキーが完全に走査されることは保証できません。開発時に考慮する必要があることです。

<?php

namespace Redis;


use Redis;

class RedisTest
{
    const PORT = 6379;

    /**
     * redis对象
     */
    public $redis = null;

    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect(&#39;127.0.0.1&#39;, self::PORT);
    }

    public function info()
    {
        print_r($this->redis->info());
    }

    /**
     * 删除前缀是test:的key
     */
    public function keyDelete()
    {
        $pre = &#39;test:&#39;;

        for ($i = 0; $i < 10; $i++) {
            $this->redis->set($pre . "$i", "$i");
        }

        // Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, &#39;del&#39;], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }
    }
}

結果を返す

array (
  0 => &#39;test:8&#39;,
)
array (
  0 => &#39;test:1&#39;,
)
array (
  0 => &#39;test:9&#39;,
)
array (
  0 => &#39;test:6&#39;,
)
array (
  0 => &#39;test:5&#39;,
)
array (
  0 => &#39;test:0&#39;,
)
array (
  0 => &#39;test:3&#39;,
)
array (
  0 => &#39;test:7&#39;,
)
array (
  0 => &#39;test:4&#39;,
)
array (
  0 => &#39;test:2&#39;,
)

SSCAN、HSCAN、ZSCAN、SCAN コマンドの落とし穴

// Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, &#39;del&#39;], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }

スキャンのドキュメントによると、次のことがわかっています。 scan コマンドでは null を返すことも可能ですが、これは終了を示すものではなく、返された繰り返しの値が "0" になった時点で終了となります。

したがって、上記のコードが反復されるときに arr_keys が返されない場合、$arr_keys は空の配列になるため、while ループは自然に中断され、出力はありません。

arr_keys が空の配列を返すという問題を回避するには、次のように解決できます。

解決策 1
 $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

Redis 拡張機能に結果セットを返すように指示します。空の場合、関数は戻らず、スキャン コマンドを直接実行し続けます。このようにして、スキャン関数が戻ると、反復が終了することを意味する false が返されます。

注: SSCAN、HSCAN、ZSCAN は同じロジックです

解決策 2

        //方式一
        // Have scan retry
        $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

        $it = NULL;
        while ($arr_keys = $this->redis->scan($it, "$pre*", 5)) {
            call_user_func_array([$this->redis, &#39;del&#39;], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }
        

        //方式二
        while (true) {
            $arr_keys = $this->redis->scan($it, "$pre*");
            if ($arr_keys === false) {//迭代结束,未找到匹配pattern的key
                return;
            }

            call_user_func_array([$this->redis, 'del'], $arr_keys);

            echo var_export($arr_keys, true) . PHP_EOL;
        }

以上がPHP Redisでキーをバッチで削除する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。