Maison  >  Article  >  base de données  >  Méthode Redis pour parcourir toutes les clés

Méthode Redis pour parcourir toutes les clés

尚
avant
2020-04-21 09:06:527074parcourir

Le raccourci clavier Redis est utilisé pour gérer les clés Redis. Cet article vous présentera deux méthodes dans Redis pour parcourir toutes les clés dans Redis - le modèle KEYS et le curseur SCAN. J'espère que cela vous sera utile.

Méthode Redis pour parcourir toutes les clés

Lorsque nous devons parcourir toutes les clés Redis ou les clés dans un mode spécifié, la première chose qui nous vient à l'esprit est la commande KEYS :

KEYS pattern

Le Le site officiel a une astuce pour la commande KEYS : KEYS est très rapide. Par exemple, il faut 40 millisecondes à Redis pour exécuter une requête dans une base de données contenant 1 million de clés. Mais son utilisation dans une grande base de données peut toujours entraîner des problèmes de performances. Si vous avez besoin de rechercher des CLÉS spécifiques à partir d'un ensemble de données, vous feriez mieux d'utiliser la structure de collection SETS de Redis.

La commande KEYS est très simple à utiliser.

redis> MSET one 1 two 2 three 3 four 4
OK
redis> KEYS *o*
1) "four"
2) "one"
3) "two"
redis> KEYS t??
1) "two"
redis> KEYS *
1) "four"
2) "three"
3) "one"
4) "two"
redis>

Mais comme la commande KEYS renvoie toutes les clés correspondantes à la fois, lorsqu'il y a trop de clés dans redis, c'est un danger caché pour la consommation de mémoire et le serveur redis

Pour Redis 2.8. La version ci-dessus nous fournit une meilleure commande SCAN pour parcourir les clés. Le format de base de cette commande est :

SCAN cursor [MATCH pattern] [COUNT count]

SCAN. Chaque exécution ne renverra qu'un petit nombre d'éléments, elle peut donc être utilisée dans des environnements de production. sans apparaître. Des problèmes tels que les commandes KEYS ou SMEMBERS qui peuvent bloquer le serveur.

La commande SCAN est un itérateur basé sur un curseur. Cela signifie qu'à chaque fois que la commande est appelée, elle doit utiliser le curseur renvoyé par l'appel précédent comme paramètre de curseur de l'appel, afin de continuer le processus d'itération précédent

Lorsque le paramètre de curseur du SCAN commande (c'est-à-dire curseur) Lorsqu'il est défini sur 0, le serveur démarrera une nouvelle itération, et lorsque le serveur renvoie un curseur avec une valeur de 0 à l'utilisateur, cela indique que l'itération est terminée.

Démonstration d'itération simple :

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

Dans l'exemple ci-dessus, la première itération utilise 0 comme curseur, indiquant le début d'une nouvelle itération. La deuxième itération utilise le curseur 17 renvoyé lors de la première itération comme nouveau paramètre d'itération.

Évidemment, la valeur de retour de la commande SCAN est un tableau contenant deux éléments. Le premier élément du tableau est le nouveau curseur utilisé pour la prochaine itération, et le deuxième élément du tableau est un autre tableau. Ce tableau contient tous les itérations. éléments.

Remarque : Le curseur renvoyé n'est pas nécessairement incrémenté. Le curseur renvoyé peut être plus petit que le précédent.

Lorsque la commande SCAN est appelée pour la deuxième fois, la commande renvoie le curseur 0, ce qui indique que l'itération est terminée et que l'ensemble des données a été complètement parcouru.

itération complète : démarrez une nouvelle itération avec 0 comme curseur et continuez à appeler la commande SCAN jusqu'à ce que la commande renvoie le curseur 0. Nous appelons ce processus un parcours complet.

La commande d'itération incrémentale SCAN ne garantit pas que chaque exécution renverra un nombre donné d'éléments, et peut même renvoyer zéro élément, mais tant que le curseur renvoyé par la commande n'est pas 0, l'application ne doit pas Traitez l’itération comme terminée.

Cependant, le nombre d'éléments renvoyés par la commande respecte toujours certaines règles. Pour un ensemble de données volumineux, la commande d'itération incrémentielle peut renvoyer jusqu'à des dizaines d'éléments à chaque fois pour un ensemble de données suffisamment petit ; , toutes les clés peuvent être renvoyées en une seule itération

Option COUNT

Pour les commandes d'itération incrémentielle qui ne garantissent pas le nombre d'éléments renvoyés dans chaque itération, nous pouvons utiliser l'option COUNT, pour le comportement de la commande est ajusté dans une certaine mesure. Le but de l'option COUNT est de permettre à l'utilisateur d'indiquer à la commande d'itération combien d'éléments doivent être renvoyés à partir de l'ensemble de données à chaque itération. L'utilisation de l'option COUNT équivaut à une astuce pour les commandes d'itération incrémentielle. Dans la plupart des cas, cette astuce est plus efficace pour contrôler le nombre de valeurs de retour.

Remarque : L'option COUNT ne contrôle pas strictement le nombre de clés renvoyées, on peut seulement dire qu'il s'agit d'une contrainte approximative. Il n'est pas nécessaire d'utiliser la même valeur COUNT pour chaque itération. L'utilisateur peut modifier la valeur COUNT selon ses besoins à chaque itération. N'oubliez pas d'utiliser le curseur renvoyé de la dernière itération à l'itération suivante.

Option MATCH

Semblable à la commande KEYS, la commande d'itération incrémentielle est implémentée en donnant le paramètre MATCH En fournissant un paramètre de mode de style global, la commande renvoie uniquement le mode correspondant. éléments. L'option

MATCH effectue une correspondance de modèles sur les éléments pendant la période après que la commande a retiré les éléments de l'ensemble de données et avant de renvoyer les éléments au client, donc s'il n'y a qu'un petit nombre d'éléments et de modèles dans Si l'ensemble de données itéré correspond, la commande d'itération peut être exécutée plusieurs fois sans renvoyer aucun élément.

Voici un exemple de cette situation :

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"
redis 127.0.0.1:6379>

Comme on peut le voir, la plupart des itérations ci-dessus ne renvoient aucun élément. Lors de la dernière itération, nous forçons la commande à analyser plus d'éléments pour cette itération en définissant le paramètre de l'option COUNT à 1000, afin que la commande renvoie plus d'éléments.

En fonction de la sécurité de SCAN, il est recommandé à tout le monde d'utiliser la commande SCAN au lieu de KEYS dans l'environnement de production. Cependant, veuillez noter que cette commande a été ajoutée après la version 2.8.0 si votre Redis est inférieur. que cette version, vous devez mettre à niveau Redis.

Ce qui suit utilise du code PHP pour démontrer l'utilisation de la commande SCAN :

<?php
 
$redis = new Redis();
 
$redis->connect(&#39;127.0.0.1&#39;, 6379);
 
 
/* 设置遍历的特性为不重复查找,该情况下扩展只会scan一次,所以可能会返回空集合 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_NORETRY);
 
$it = NULL;
$pattern = &#39;*&#39;;
$count = 50;  // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
 
do
{
    $keysArr = $redis->scan($it, $pattern, $count);
 
    if ($keysArr)
    {
        foreach ($keysArr as $key)
        {
            echo $key . "\n";
        }
    }
 
} while ($it > 0);   //每次调用 Scan会自动改变 $it 值,当$it = 0时 这次遍历结束 退出循环
 
 
echo &#39;---------------------------------------------------------------------------------&#39; . "\n";
 
 
/* 设置扩展在一次scan没有查找出记录时 进行重复的scan 直到查询出结果或者遍历结束为止 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
 
$it = NULL;
$pattern = &#39;*&#39;;
$count = 50;  // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
 
//这种用法下我们只需要简单判断返回结果是否为空即可, 如果为空说明遍历结束
while ($keysArr = $redis->scan($it, $pattern, $count))
{
    foreach ($keysArr as $key)
    {
        echo $key . "\n";
    }
}

Résultat de l'exécution :

[root@localhost php]# /usr/local/php/bin/php scan.php 
bm
bm2
h1
name
bit
bm1
places
cities
hhl
---------------------------------------------------------------------------------
bm
bm2
h1
name
bit
bm1
places
cities
hhl

注意:如果php执行报错 请升级到较新版本的Redis扩展。

更多redis知识请关注redis入门教程栏目。

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer