Heim  >  Artikel  >  Datenbank  >  Redis-Methode zum Durchlaufen aller Schlüssel

Redis-Methode zum Durchlaufen aller Schlüssel

尚
nach vorne
2020-04-21 09:06:527061Durchsuche

Der Redis-Tastenbefehl wird zum Verwalten von Redis-Schlüsseln verwendet. In diesem Artikel werden Ihnen zwei Methoden in Redis zum Durchlaufen aller Schlüssel in Redis vorgestellt – das KEYS-Muster und der SCAN-Cursor. Ich hoffe, dass es Ihnen hilfreich sein wird.

Redis-Methode zum Durchlaufen aller Schlüssel

Wenn wir alle Redis-Schlüssel oder Schlüssel in einem bestimmten Modus durchlaufen müssen, fällt uns als Erstes der KEYS-Befehl ein:

KEYS pattern

The Auf der offiziellen Website gibt es einen Tipp für den Befehl KEYS: KEYS ist sehr schnell. Beispielsweise dauert es 40 Millisekunden, bis Redis eine Abfrage in einer Datenbank mit 1 Million Schlüsseln ausführt. Die Verwendung in einer großen Datenbank kann jedoch immer noch zu Leistungsproblemen führen. Wenn Sie bestimmte SCHLÜSSEL aus einem Datensatz finden müssen, verwenden Sie stattdessen besser die Sammlungsstruktur SETS von Redis.

Der KEYS-Befehl ist sehr einfach zu verwenden.

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>

Da der Befehl KEYS jedoch alle passenden Schlüssel auf einmal zurückgibt, besteht bei zu vielen Schlüsseln in Redis eine versteckte Gefahr für den Speicherverbrauch und den Redis-Server.

Für Redis 2.8 Die obige Version bietet uns einen besseren Befehl SCAN zum Durchlaufen von Schlüsseln. Das Grundformat dieses Befehls ist:

SCAN cursor [MATCH pattern] [COUNT count]

SCAN. Jede Ausführung gibt nur eine kleine Anzahl von Elementen zurück, sodass er in Produktionsumgebungen verwendet werden kann ohne dass Probleme wie KEYS- oder SMEMBERS-Befehle auftreten, die den Server blockieren können.

Der SCAN-Befehl ist ein Cursor-basierter Iterator. Dies bedeutet, dass bei jedem Aufruf des Befehls der vom vorherigen Aufruf zurückgegebene Cursor als Cursor-Parameter des Aufrufs verwendet werden muss, um den vorherigen Iterationsprozess fortzusetzen

Wenn der Cursor-Parameter des SCAN Befehl (d. h. Cursor) Wenn auf 0 gesetzt, startet der Server eine neue Iteration. Wenn der Server einen Cursor mit dem Wert 0 an den Benutzer zurückgibt, bedeutet dies, dass die Iteration beendet ist.

Einfache Iterationsdemonstration:

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"

Im obigen Beispiel verwendet die erste Iteration 0 als Cursor, was den Beginn einer neuen Iteration angibt. Die zweite Iteration verwendet den in der ersten Iteration zurückgegebenen Cursor 17 als neuen Iterationsparameter.

Offensichtlich ist der Rückgabewert des SCAN-Befehls ein Array, das zwei Elemente enthält. Das erste Array-Element ist der neue Cursor, der für die nächste Iteration verwendet wird, und das zweite Array-Element ist ein weiteres Array. Dieses Array enthält alle iterierten Elemente Elemente.

Hinweis: Der zurückgegebene Cursor wird nicht unbedingt inkrementiert. Der zurückgegebene Cursor ist möglicherweise kleiner als der vorherige.

Wenn der SCAN-Befehl zum zweiten Mal aufgerufen wird, gibt der Befehl den Cursor 0 zurück, was anzeigt, dass die Iteration beendet ist und der gesamte Datensatz vollständig durchlaufen wurde.

Vollständige Iteration: Starten Sie eine neue Iteration mit 0 als Cursor und rufen Sie den SCAN-Befehl so lange auf, bis der Befehl den Cursor 0 zurückgibt. Wir nennen diesen Prozess eine vollständige Durchquerung.

Der inkrementelle Iterationsbefehl SCAN garantiert nicht, dass jede Ausführung eine bestimmte Anzahl von Elementen zurückgibt, und kann sogar null Elemente zurückgeben, aber solange der vom Befehl zurückgegebene Cursor nicht 0 ist, sollte die Anwendung dies nicht tun Behandeln Sie die Iteration als abgeschlossen.

Die Anzahl der vom Befehl zurückgegebenen Elemente entspricht jedoch immer bestimmten Regeln. Bei einem großen Datensatz kann der inkrementelle Iterationsbefehl bei ausreichend kleinen Daten jedes Mal bis zu Dutzende von Elementen zurückgeben , alle Schlüssel können in einer Iteration zurückgegeben werden

COUNT-Option

Für inkrementelle Iterationsbefehle, die die Anzahl der in jeder Iteration zurückgegebenen Elemente nicht garantieren, können wir die COUNT-Option für das Verhalten verwenden des Befehls wird teilweise angepasst. Der Zweck der COUNT-Option besteht darin, dem Benutzer zu ermöglichen, dem Iterationsbefehl mitzuteilen, wie viele Elemente in jeder Iteration aus dem Datensatz zurückgegeben werden sollen. Die Verwendung der COUNT-Option entspricht einem Hinweis für inkrementelle Iterationsbefehle. In den meisten Fällen ist dieser Hinweis effektiver bei der Steuerung der Anzahl der Rückgabewerte.

Hinweis: Die COUNT-Option kontrolliert nicht streng die Anzahl der zurückgegebenen Schlüssel, es kann nur gesagt werden, dass es sich um eine grobe Einschränkung handelt. Es ist nicht notwendig, für jede Iteration denselben COUNT-Wert zu verwenden. Der Benutzer kann den COUNT-Wert bei jeder Iteration nach Bedarf ändern. Denken Sie daran, den von der letzten Iteration zurückgegebenen Cursor zu verwenden.

MATCH-Option

Ähnlich wie der KEYS-Befehl wird der inkrementelle Iterationsbefehl durch Angabe des MATCH-Parameters implementiert, indem der Befehl nur den angegebenen Modus zurückgibt Elemente. Die Option

MATCH führt einen Mustervergleich für Elemente während des Zeitraums durch, nachdem der Befehl die Elemente aus dem Datensatz entfernt hat und bevor die Elemente an den Client zurückgegeben werden, also wenn nur eine kleine Anzahl von Elementen und Mustern vorhanden sind Wenn der iterierte Datensatz übereinstimmt, kann der Iterationsbefehl mehrmals ausgeführt werden, ohne dass Elemente zurückgegeben werden.

Hier ist ein Beispiel für diese 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>

Wie zu sehen ist, geben die meisten der oben genannten Iterationen keine Elemente zurück. In der letzten Iteration zwingen wir den Befehl, weitere Elemente für diese Iteration zu scannen, indem wir den Parameter der COUNT-Option auf 1000 setzen, sodass der Befehl mehr Elemente zurückgibt.

Aufgrund der Sicherheit von SCAN wird empfohlen, dass jeder den SCAN-Befehl anstelle von KEYS in der Produktionsumgebung verwendet. Bitte beachten Sie, dass dieser Befehl nach Version 2.8.0 hinzugefügt wurde Als diese Version müssen Sie Redis aktualisieren.

Im Folgenden wird PHP-Code verwendet, um die Verwendung des SCAN-Befehls zu demonstrieren:

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

Ausführungsergebnis:

[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入门教程栏目。

Das obige ist der detaillierte Inhalt vonRedis-Methode zum Durchlaufen aller Schlüssel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen