>백엔드 개발 >PHP 문제 >PHP Redis에서 일괄적으로 키를 삭제하는 방법

PHP Redis에서 일괄적으로 키를 삭제하는 방법

藏色散人
藏色散人원래의
2020-10-07 00:38:095810검색

PHP Redis에서 일괄적으로 키를 삭제하는 방법: 먼저 명령 창을 연 다음 "redis-cli 키 비디오* | xargs redis-cli del" 명령을 사용하여 일괄적으로 키를 삭제합니다.

PHP Redis에서 일괄적으로 키를 삭제하는 방법

redis는 키 삭제 기능을 일괄적으로 구현합니다

권장: "PHP Video Tutorial"

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命令渐进式的遍历所有键,可以有效防止阻塞。

Progressive traversal

scan 명령 문서화

Redis는 명령줄에서 해시 유형, 집합 유형 및 순서 집합에 대한 스캔 순회 명령을 제공합니다. , hgetall, smembers 및 zrange와 같은 가능한 차단 문제를 해결하기 위해 해당 명령은 hscan, sscan 및 zscan이며 사용법은 기본적으로 scan과 유사합니다.

참고:
점진적 순회는 키 명령으로 인해 발생할 수 있는 차단 문제를 효과적으로 해결할 수 있지만 검색이 완벽하지는 않습니다. 검색 프로세스 중에 키에 변경 사항(추가, 삭제, 수정)이 있으면
순회 효과가 발생합니다. 새로 추가된 키가 탐색되지 않거나, 중복 키가 탐색될 수 있는 등의 문제에 직면할 수 있습니다. 즉, 스캔은 모든 키가 완전히 탐색된다는 것을 보장할 수 없습니다. 이러한 사항은 개발 중에 고려해야 할 사항입니다.

<?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 문서에 따르면 scan 명령은 각 반복 중에 null을 반환할 수 있지만 이는 끝을 알리는 신호가 아닙니다. , 반환된 반복 값이 "0"일 때 종료됩니다.

따라서 위 코드가 iterating할 때 arr_keys가 반환되지 않으면 $arr_keys는 빈 배열이므로 while 루프가 자연스럽게 중단되어 출력이 없습니다.

arr_keys가 빈 배열을 반환하는 문제를 피하기 위해 다음과 같이 해결할 수 있습니다.

해결책 1
 $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

Redis 확장 프로그램에 scan 명령을 실행한 후 반환된 결과 집합이 비어 있으면 함수가 반환되지 않고 직접 계속됩니다. 스캔 명령을 실행합니다. 이런 방식으로 스캔 함수가 반환되면 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.