Home > Backend Development > PHP Problem > How to delete keys in batches in php redis

How to delete keys in batches in php redis

藏色散人
Release: 2023-03-06 13:18:02
Original
5815 people have browsed it

php How to delete keys in batches from redis: First open the command window; then use the command "redis-cli keys video* | xargs redis-cli del" to delete keys in batches.

How to delete keys in batches in php redis

redis implements batch deletion key function

Recommended: "PHP Video Tutorial"

keys

When using redis in the test environment, we often need to delete keys in batches. However, redis does not provide a batch deletion command, but we can use keys to traverse keys on the command line. Implementation

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

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

Progressive traversal

scan command documentation

Redis provides scan traversal commands for hash types, collection types, and ordered collections to solve problems such as hgetall and smembers , zrange may cause blocking problems, the corresponding commands are hscan, sscan, zscan, their usage is basically similar to scan.

Note:
Progressive traversal can effectively solve the blocking problem that may occur with the keys command, but the scan is not perfect. If there are key changes (added, deleted) during the scan process , modification),
Then the traversal effect may encounter the following problems: newly added keys may not be traversed, duplicate keys may be traversed, etc. In other words, scan cannot guarantee that all keys will be traversed completely. These are things we need to consider when developing.

<?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;
        }
    }
}
Copy after login

Return results

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;,
)
Copy after login

The pitfalls of SSCAN, HSCAN, ZSCAN, and SCAN commands

// 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;
        }
Copy after login

According to the scan documentation, we know: each iteration of the scan command , it is possible to return null, but this is not a sign of the end. It is the end when the value of the returned iteration is "0".

Therefore, when the above code is iterating, if no arr_keys is returned, $arr_keys is an empty array, so the while loop is naturally interrupted, so there is no output.

In order to avoid the problem that arr_keys returns an empty array, we can solve it like this:

Solution 1
 $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
Copy after login

Tell the redis extension to return the result set when the scan command is executed. If it is empty, the function does not return, but continues to execute the scan command directly. In this way, when the scan function returns, it will either return false, which means the iteration ends.

Note: SSCAN, HSCAN, and ZSCAN have the same logic

Solution 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;
        }
Copy after login

The above is the detailed content of How to delete keys in batches in php redis. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template