Heim > Backend-Entwicklung > PHP-Problem > So löschen Sie Schlüssel stapelweise in PHP Redis

So löschen Sie Schlüssel stapelweise in PHP Redis

藏色散人
Freigeben: 2023-03-06 13:18:02
Original
5810 Leute haben es durchsucht

So löschen Sie Schlüssel stapelweise in PHP Redis: Öffnen Sie zuerst das Befehlsfenster. Verwenden Sie dann den Befehl „redis-cli keys video* | xargs redis-cli del“, um Schlüssel stapelweise zu löschen.

So löschen Sie Schlüssel stapelweise in PHP Redis

redis implementiert die Funktion zum Löschen von Schlüsseln in Stapeln Wir haben kein Redis, das Batch-Löschbefehle bereitstellt, aber wir können Key-Traversal-Keys verwenden, um

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

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

Progressive Traversal

Scan-Befehlsdokumentation

Redis bietet Scan-Traversal-Befehle für Hash-Typen, Set-Typen und geordnete Sets unter der Befehlszeile , um mögliche Blockierungsprobleme wie hgetall, smembers und zrange zu lösen. Die entsprechenden Befehle sind hscan, sscan und zscan. Ihre Verwendung ähnelt im Wesentlichen der von scan.

Hinweis:

Progressive Durchquerung kann das Blockierungsproblem, das der Tastenbefehl verursachen kann, effektiv lösen, aber der Scan ist nicht perfekt. Wenn sich während des Scanvorgangs Änderungen an den Schlüsseln ergeben (hinzugefügt, gelöscht, geändert),

dann der Durchquerungseffekt Es können folgende Probleme auftreten: Neu hinzugefügte Schlüssel werden möglicherweise nicht durchlaufen, doppelte Schlüssel werden möglicherweise nicht durchlaufen usw. Mit anderen Worten: Der Scan kann nicht garantieren, dass alle Schlüssel vollständig durchlaufen werden. Dies sind Dinge, die wir bei der Entwicklung berücksichtigen müssen.

<?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;
        }
    }
}
Nach dem Login kopieren
Ergebnisse zurückgeben

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;,
)
Nach dem Login kopieren

Fallstricke von SSCAN-, HSCAN-, ZSCAN- und SCAN-Befehlen
// 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;
        }
Nach dem Login kopieren

Laut Dokumentation des Scans: Der Scan-Befehl kann bei jeder Iteration null zurückgeben, aber das ist kein Zeichen des Endes , endet es, wenn der Wert der zurückgegebenen Iteration „0“ ist.

Wenn also der obige Code iteriert und kein arr_keys zurückgegeben wird, ist $arr_keys ein leeres Array, sodass die while-Schleife natürlich unterbrochen wird und keine Ausgabe erfolgt.

Um das Problem zu vermeiden, dass arr_keys ein leeres Array zurückgibt, können wir es wie folgt lösen:

Lösung 1

 $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
Nach dem Login kopieren

Teilen Sie der Redis-Erweiterung mit, dass die Funktion nach der Ausführung des Scan-Befehls leer ist, wenn die zurückgegebene Ergebnismenge leer ist kehrt nicht zurück, sondern führt den Scan-Befehl direkt aus. Auf diese Weise gibt die Scan-Funktion bei der Rückkehr entweder false zurück, was bedeutet, dass die Iteration endet.

Hinweis: SSCAN, HSCAN und ZSCAN haben die gleiche Logik

Lösung 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;
        }
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonSo löschen Sie Schlüssel stapelweise in PHP Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage