Maison  >  Article  >  développement back-end  >  Comment supprimer des clés par lots dans php redis

Comment supprimer des clés par lots dans php redis

藏色散人
藏色散人original
2020-10-07 00:38:095753parcourir

Comment supprimer des clés par lots dans PHP redis : ouvrez d'abord la fenêtre de commande ; puis utilisez la commande "redis-cli keys video* | xargs redis-cli del" pour supprimer les clés par lots.

Comment supprimer des clés par lots dans php redis

redis implémente la fonction de clé de suppression par lots

Recommandé : "Tutoriel vidéo PHP"

clés

Lors de l'utilisation de Redis dans l'environnement de test, nous devons souvent supprimer les clés par lots. Cependant, Redis ne fournit pas de commande de suppression par lots, mais nous pouvons utiliser des clés pour parcourir les clés sur le. ligne de commande. Implémentez

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

Traversée progressive

documentation sur les commandes d'analyse

Redis fournit des commandes de traversée d'analyse pour les types de hachage, les types d'ensembles et les ensembles ordonnés pour résoudre des problèmes tels que hgetall et smembers , zrange peuvent provoquer des problèmes de blocage, les commandes correspondantes sont hscan, sscan, zscan, leur utilisation est fondamentalement similaire à scan.

Remarque :
Le parcours progressif peut résoudre efficacement le problème de blocage qui peut survenir avec la commande touches, mais l'analyse n'est pas parfaite s'il y a des changements de clés (ajoutés, supprimés) pendant l'analyse. processus , modification),
Ensuite, l'effet de traversée peut rencontrer les problèmes suivants : les clés nouvellement ajoutées peuvent ne pas être parcourues, les clés en double peuvent être parcourues, etc. En d'autres termes, l'analyse ne peut pas garantir que toutes les clés seront complètement parcourues. sont des choses que nous devons prendre en compte lors du développement.

<?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;
        }
    }
}

Résultats de retour

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;,
)

Pièges des commandes 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;
        }

Selon la documentation de scan : chaque itération de la commande scan, il est possible de renvoyer null, mais ce n'est pas un signe de fin. C'est la fin lorsque la valeur de l'itération renvoyée est "0".

Par conséquent, lorsque le code ci-dessus est itéré, si aucun arr_keys n'est renvoyé, $arr_keys est un tableau vide, donc la boucle while est naturellement interrompue, donc il n'y a pas de sortie.

Afin d'éviter le problème selon lequel arr_keys renvoie un tableau vide, nous pouvons le résoudre comme ceci :

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

Dites à l'extension redis de renvoyer l'ensemble de résultats après l'exécution de la commande scan S'il est vide, la fonction ne renvoie pas, mais continue d'exécuter directement la commande scan. De cette façon, lorsque la fonction scan reviendra, elle renverra soit false, ce qui signifie que l'itération se termine.

Remarque : SSCAN, HSCAN et ZSCAN ont la même logique

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;
        }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn