Dies ist ein so häufiges Szenario, dass ich mir wünschte, das Redis-Team würde erwägen, einen nativen Befehl dafür hinzuzufügen.
Todd Menier
Heutzutage kann man das einfach mit Lua machen, siehe unten.
Alexander Gladysh
3
@ToddMenier Ich habe gerade vorgeschlagen, diese Argumentation zurückzubekommen, warum es niemals passieren wird: github.com/antirez/redis/issues/2042
Ray
1
Viele Leute stellen verwandte Fragen zum Umgang mit einer großen Anzahl von Schlüsseln, Schlüsseln mit Sonderzeichen usw. Ich habe eine separate Frage erstellt, da wir dieses Problem jetzt haben und ich glaube nicht, dass die Antwort auf diese Frage veröffentlicht wird. Hier ist die andere Frage: stackoverflow.com/questions/32890648/…
jakejgordon
Antworten:
431
Ab redis 2.6.0 können Sie lua-Skripte ausführen, die atomar ausgeführt werden. Ich habe noch nie einen geschrieben, aber ich denke, er würde ungefähr so aussehen
Warnung : Wie im Redis-Dokument angegeben, keys
sollte der Befehl aus Leistungsgründen nicht für reguläre Vorgänge in der Produktion verwendet werden. Dieser Befehl ist für das Debuggen und spezielle Vorgänge vorgesehen. Weiterlesen
Wichtiger Hinweis: Dies schlägt fehl, wenn Sie mehr als ein paar tausend Schlüssel haben, die dem Präfix entsprechen.
Nathan Osman
93
Dieser arbeitet für eine große Anzahl von Schlüsseln:EVAL "local keys = redis.call('keys', ARGV[1]) \n for i=1,#keys,5000 do \n redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) \n end \n return keys" 0 prefix:*
Sheerun
181
Autsch ... redis wird häufig als einfacher Schlüssel- / Speicher-Cache verwendet. Dies scheint del prefix:* eine grundlegende Operation zu sein: /
Ray
5
@ Ray ehrlich gesagt, wenn Sie diese Funktion benötigen, sollten Sie einfach die Daten nach numetischen Datenbank oder Server partitionieren und Flush / Flushdb
Marc Gravell verwenden
9
Ja, es schlägt fehl, wenn kein Schlüssel mit dem Muster übereinstimmt. Um das zu beheben, habe ich einen Standardschlüssel hinzugefügt:EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
manuelmhtr
706
In Bash ausführen:
redis-cli KEYS "prefix:*" | xargs redis-cli DEL
AKTUALISIEREN
OK ich habe verstanden. Was ist mit dieser Methode: Speichern Sie das aktuelle zusätzliche inkrementelle Präfix und fügen Sie es allen Ihren Schlüsseln hinzu. Zum Beispiel:
Wenn Sie Daten löschen müssen, ändern Sie zuerst prefix_actuall (z. B. setzen Sie prefix_prefix_actuall = 3), damit Ihre Anwendung neue Daten in das Schlüsselpräfix 3: 1 und das Präfix 3: 2 schreibt. Dann können Sie sicher alte Werte aus Präfix: 2: 1 und Präfix: 2: 2 übernehmen und alte Schlüssel löschen.
Entschuldigung, aber dies ist keine atomare Löschung. Jemand kann neue Schlüssel zwischen KEYS und DEL hinzufügen. Ich möchte diese nicht löschen.
Alexander Gladysh
36
Schlüssel, die nach dem Befehl KEYS erstellt werden, werden nicht gelöscht.
Casey
6
Ich musste nur einige fehlerhafte Schlüssel entfernen, also war Caseys erste Antwort genau richtig, außer dass ich Schlüssel außerhalb der Anführungszeichen verschieben musste: redis-cli KEYS "Präfix: *" | xargs redis-cli DEL
jslatts
19
Die erste Antwort hat mir auch geholfen. Eine andere Variante, wenn Ihre Redis-Schlüssel Anführungszeichen oder andere Zeichen enthalten, die xargs redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
durcheinander bringen
18
Wenn Sie mehrere Datenbanken (Keyspaces) haben, dann ist dies der Trick: Nehmen wir an, Sie müssen Schlüssel in db3 löschen:redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Christoffer
73
Hier ist eine vollständig funktionierende und atomare Version eines in Lua implementierten Wildcard-Löschvorgangs. Es läuft viel schneller als die xargs-Version, da das Netzwerk viel weniger hin und her geht, und es ist vollständig atomar und blockiert alle anderen Anforderungen gegen Redis, bis es fertig ist. Wenn Sie Schlüssel in Redis 2.6.0 oder höher atomar löschen möchten, ist dies definitiv der richtige Weg:
Dies ist eine funktionierende Version von @ mcdizzles Idee in seiner Antwort auf diese Frage. Die Idee zu 100% geht an ihn.
BEARBEITEN: Laut Kikitos Kommentar unten tritt der Fehler "Zu viele Elemente zum Entpacken" auf , wenn Sie mehr Schlüssel zum Löschen als freien Speicher auf Ihrem Redis-Server haben . In diesem Fall tun Sie:
for _,k in ipairs(redis.call('keys', ARGV[1])) do
redis.call('del', k)
end
Der obige Code wird angezeigt, wenn Sie eine erhebliche Anzahl von Schlüsseln haben (der Fehler lautet "zu viele Elemente zum Entpacken"). Ich empfehle die Verwendung einer Schleife für den Lua-Teil:for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
Kikito
@kikito, ja, wenn lua den Stapel nicht auf die Anzahl der zu löschenden Schlüssel vergrößern kann (höchstwahrscheinlich aufgrund von Speichermangel), müssen Sie dies mit einer for-Schleife tun. Ich würde es nicht empfehlen, es sei denn, Sie müssen.
Eli
1
Lua unpacktransformiert eine Tabelle in eine "Liste unabhängiger Variablen" (andere Sprachen nennen das explode), aber die maximale Anzahl hängt nicht vom Systemspeicher ab. Es ist in Lua durch die LUAI_MAXSTACKKonstante festgelegt. In Lua 5.1 & LuaJIT sind es 8000 und in Lua 5.2 100000. Die Option for loop wird IMO empfohlen.
Kikito
1
Es ist erwähnenswert, dass Lua-
Skripte
1
Jede Lua-basierte Lösung verstößt gegen die Semantik von, EVALda sie die Schlüssel, mit denen sie arbeiten wird, nicht im Voraus angibt. Es sollte auf einer einzelnen Instanz funktionieren, aber erwarten Sie nicht, dass es mit Redis Cluster funktioniert.
Kevin Christopher Henry
66
Haftungsausschluss: Die folgende Lösung bietet keine Atomizität.
Ab v2.8 bist du wirklich möchten den Befehl SCAN anstelle von KEYS [1] verwenden. Das folgende Bash-Skript demonstriert das Löschen von Schlüsseln nach Muster:
#!/bin/bash
if [ $# -ne 3 ]
then
echo "Delete keys from Redis matching a pattern using SCAN & DEL"
echo "Usage: $0 <host> <port> <pattern>"
exit 1
fi
cursor=-1
keys=""
while [ $cursor -ne 0 ]; do
if [ $cursor -eq -1 ]
then
cursor=0
fi
reply=`redis-cli -h $1 -p $2 SCAN $cursor MATCH $3`
cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'`
keys=${reply##[0-9]*[0-9 ]}
redis-cli -h $1 -p $2 DEL $keys
done
[1] KEYS ist ein gefährlicher Befehl, der möglicherweise zu einem DoS führen kann. Das Folgende ist ein Zitat aus der Dokumentationsseite:
Warnung: Betrachten Sie KEYS als Befehl, der nur in Produktionsumgebungen mit äußerster Sorgfalt verwendet werden sollte. Dies kann die Leistung beeinträchtigen, wenn es für große Datenbanken ausgeführt wird. Dieser Befehl dient zum Debuggen und für spezielle Vorgänge, z. B. zum Ändern des Keyspace-Layouts. Verwenden Sie KEYS nicht in Ihrem regulären Anwendungscode. Wenn Sie nach einer Möglichkeit suchen, Schlüssel in einer Teilmenge Ihres Schlüsselraums zu finden, sollten Sie Mengen verwenden.
UPDATE: Ein Einzeiler für den gleichen Grundeffekt -
Das Vermeiden von KEYS wird jedoch definitiv als bewährte Methode angesehen. Daher ist dies eine großartige Lösung, wenn nicht-atomare Löschungen möglich sind.
fatal_error
Das hat bei mir funktioniert; Meine Schlüssel befanden sich jedoch zufällig in Datenbank 1. Also musste ich -n 1jedem redis-cliAufruf Folgendes hinzufügen :redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
Rob Johansen
Beachten Sie, dass dies nicht funktioniert, wenn Ihre Schlüssel spezielle Zeichen enthalten
mr1031011
Interessanter und wertvoller Fund ... Ich frage mich, ob es eine Möglichkeit gibt, Dinge für Xargs zu zitieren ...
Itamar Haber
Was macht -L 100?
Aparna
41
Für diejenigen, die Probleme hatten, andere Antworten zu analysieren:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
Ersetzen Sie key:*:patterndurch Ihr eigenes Muster und geben Sie dieses einredis-cli und Sie können loslegen.
redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL
Weitere Hilfe zur Suche nach Schlüsselmustern erhalten Sie hier: - https://redis.io/commands/keys . Verwenden Sie Ihr praktisches Muster im Glob-Stil gemäß Ihren Anforderungen wie *YOUR_KEY_PREFIX*oderYOUR_KEY_PREFIX?? oder andere.
Und wenn einer von Ihnen die Redis PHP-Bibliothek integriert hat, hilft Ihnen die folgende Funktion.
flushRedisMultipleHashKeyUsingPattern("*YOUR_KEY_PATTERN*"); //function call
function flushRedisMultipleHashKeyUsingPattern($pattern='')
{
if($pattern==''){
return true;
}
$redisObj = $this->redis;
$getHashes = $redisObj->keys($pattern);
if(!empty($getHashes)){
$response = call_user_func_array(array(&$redisObj, 'del'), $getHashes); //setting all keys as parameter of "del" function. Using this we can achieve $redisObj->del("key1","key2);
}
}
Die Verwendung von Lua ist loooooot schneller als die Verwendung von Xargs in der Reihenfolge 10 ^ 4.
Deepak
22
Mit diesem Befehl können Sie auch die Schlüssel löschen: -
Angenommen, Ihre Redis enthalten viele Arten von Schlüsseln.
'xyz_category_fpc_12'
'xyz_category_fpc_245'
'xyz_category_fpc_321'
'xyz_product_fpc_876'
'xyz_product_fpc_302'
'xyz_product_fpc_01232'
Beispiel: ' xyz_category_fpc ' hier ist xyz ein Site-Name . Diese Schlüssel beziehen sich auf Produkte und Kategorien einer E-Commerce-Site und werden von FPC generiert.
Wenn Sie diesen Befehl wie folgt verwenden:
redis-cli --scan --pattern 'key*' | xargs redis-cli del
ODER
redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del
Es löscht alle Schlüssel wie ' xyz_category_fpc ' (lösche 1, 2 und 3 Schlüssel). Verwenden Sie zum Löschen anderer 4, 5 und 6 Zifferntasten ' xyz_product_fpc ' im obigen Befehl.
Wenn Sie alles in Redis löschen möchten , befolgen Sie diese Befehle.
Mit redis-cli:
FLUSHDB - Entfernt Daten aus der CURRENT-Datenbank Ihrer Verbindung.
@ itamars Antwort ist großartig, aber das Parsen der Antwort hat bei mir nicht funktioniert, insb. in dem Fall, in dem in einem bestimmten Scan keine Schlüssel gefunden wurden. Eine möglicherweise einfachere Lösung direkt von der Konsole aus:
redis-cli -h HOST -p PORT --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL
Dies verwendet auch SCAN, das KEYS in der Produktion vorzuziehen ist, aber nicht atomar ist.
Ich hatte gerade das gleiche Problem. Ich habe Sitzungsdaten für einen Benutzer im folgenden Format gespeichert:
session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z
Jeder Eintrag war also ein separates Schlüssel-Wert-Paar. Wenn die Sitzung zerstört wird, wollte ich alle Sitzungsdaten entfernen, indem ich Schlüssel mit dem Muster session:sessionid:*lösche - aber redis hat keine solche Funktion.
Was ich getan habe: Speichern Sie die Sitzungsdaten in einem Hash . Ich schaffe nur einen Hash mit der Hash - ID von session:sessionidund dann schiebe ich key-x, key-y, key-zdass Hash (um mich nicht Sache tat) , und wenn ich nicht brauchen , dass Hash mehr ich nur zu tun , DEL session:sessionidund alle Daten mit der Hash - ID zugeordnet sind weg. DEList atomar und der Zugriff auf Daten / das Schreiben von Daten in den Hash ist O (1).
Aber ich kann hier nicht herausfinden, wie ich sie verwenden soll. DEL ist an sich atomar (oder so denke ich). Und ich kann keine Werte von KEYS erhalten, bis ich EXEC mache, also kann ich KEYS und DEL nicht in derselben MULTI verwenden.
Alexander Gladysh
5
Zu Ihrer Information.
nur mit bash und redis-cli
nicht verwenden keys(dies verwendet scan)
funktioniert gut im Cluster-Modus
nicht atomar
Möglicherweise müssen Sie nur Großbuchstaben ändern.
scan-match.sh
#!/bin/bash
rcli=“/YOUR_PATH/redis-cli"
default_server="YOUR_SERVER"
default_port="YOUR_PORT"
servers=`$rcli -h $default_server -p $default_port cluster nodes | grep master | awk '{print $2}' | sed 's/:.*//'`
if [ x"$1" == "x" ]; then
startswith="DEFAULT_PATTERN"
else
startswith="$1"
fi
MAX_BUFFER_SIZE=1000
for server in $servers; do
cursor=0
while
r=`$rcli -h $server -p $default_port scan $cursor match "$startswith*" count $MAX_BUFFER_SIZE `
cursor=`echo $r | cut -f 1 -d' '`
nf=`echo $r | awk '{print NF}'`
if [ $nf -gt 1 ]; then
for x in `echo $r | cut -f 1 -d' ' --complement`; do
echo $x
done
fi
(( cursor != 0 ))
do
:
done
done
clear-redis-key.sh
#!/bin/bash
STARTSWITH="$1"
RCLI=YOUR_PATH/redis-cli
HOST=YOUR_HOST
PORT=6379
RCMD="$RCLI -h $HOST -p $PORT -c "
./scan-match.sh $STARTSWITH | while read -r KEY ; do
$RCMD del $KEY
done
Andere Antworten funktionieren möglicherweise nicht, wenn Ihr Schlüssel spezielle Zeichen enthält - Guide$CLASSMETADATA][1]zum Beispiel. Wenn Sie jeden Schlüssel in Anführungszeichen setzen, wird sichergestellt, dass er ordnungsgemäß gelöscht wird:
redis-cli --scan --pattern sf_*| awk '{print $1}'| sed "s/^/'/;s/$/'/"| xargs redis-cli del
Dieses Skript funktioniert perfekt und wurde mit mehr als 25000 Schlüsseln getestet.
Jordi
1
Sie können die einfachen Anführungszeichen auch in awk hinzufügen, indem Sie diesen lustigen Ausdruck "awk" {print "" "" $ 1 "" "}" "
Roberto Congiu
3
Eine Version, die SCAN anstelle von KEYS (wie für Produktionsserver empfohlen) und --pipenicht von xargs verwendet.
Ich bevorzuge Pipe gegenüber Xargs, weil es effizienter ist und funktioniert, wenn Ihre Schlüssel Anführungszeichen oder andere Sonderzeichen enthalten, mit denen Ihre Shell versucht, sie zu interpretieren. Die Regex-Ersetzung in diesem Beispiel umschließt den Schlüssel in doppelte Anführungszeichen und entgeht allen doppelten Anführungszeichen.
Diese Lösung hat bei mir auch bei ca. 7m Schlüsseln gut funktioniert!
Danny
2
Dies ist keine direkte Antwort auf die Frage, aber da ich bei der Suche nach meinen eigenen Antworten hierher gekommen bin, werde ich dies hier teilen.
Wenn Sie Dutzende oder Hunderte von Millionen von Schlüsseln haben, die Sie abgleichen müssen, führen die hier gegebenen Antworten dazu, dass Redis längere Zeit (Minuten?) Nicht reagiert und möglicherweise aufgrund des Speicherverbrauchs abstürzt (stellen Sie sicher, dass das Speichern im Hintergrund funktioniert) treten Sie mitten in Ihrer Operation ein).
Der folgende Ansatz ist zweifellos hässlich, aber ich habe keinen besseren gefunden. Atomarität kommt hier nicht in Frage. In diesem Fall besteht das Hauptziel darin, Redis 100% der Zeit auf dem Laufenden zu halten und zu reagieren. Es funktioniert perfekt, wenn Sie alle Schlüssel in einer der Datenbanken haben und kein Muster abgleichen müssen, aber http://redis.io/commands/FLUSHDB nicht verwenden können, da es die Natur blockiert.
Wenn es einen besseren Weg gibt, lass es mich wissen, ich werde die Antwort aktualisieren.
Beispielimplementierung mit randomkey in Ruby als Rake-Task, ein nicht blockierender Ersatz für etwas wie redis-cli -n 3 flushdb:
desc 'Cleanup redis'
task cleanup_redis: :environment do
redis = Redis.new(...) # connection to target database number which needs to be wiped out
counter = 0
while key = redis.randomkey
puts "Deleting #{counter}: #{key}"
redis.del(key)
counter += 1
end
end
Ich habe die meisten der oben genannten Methoden ausprobiert, aber sie haben bei mir nicht funktioniert. Nach einigen Suchanfragen habe ich folgende Punkte gefunden:
Wenn Sie mehr als eine Datenbank auf Redis haben, sollten Sie die Datenbank mithilfe von bestimmen -n [number]
wenn Sie ein paar Tasten verwenden , delaber wenn es Tausende oder Millionen von Schlüsseln sind , ist es besser zu nutzen , unlinkweil unlink ist non-blocking , während del blockiert, für weitere Informationen besuchen Sie diese Seite unlink vs del
auch keyssind wie del und blockiert
Also habe ich diesen Code verwendet, um Schlüssel nach Muster zu löschen:
Vielleicht könnten Sie sie alle so einstellen, dass sie in derselben Sekunde ablaufen - wie einige Minuten in der Zukunft - und dann bis zu diesem Zeitpunkt warten und sie alle gleichzeitig "selbstzerstörend" sehen.
aber ich bin mir nicht sicher, wie atomar das wäre.
Ab sofort können Sie einen Redis-Client verwenden und zuerst SCAN (unterstützt Pattern Matching) durchführen und dann jeden Schlüssel einzeln löschen.
Allerdings gibt es ein Problem auf der offiziellen redis GitHub einen Rüttler-Matching-del zu schaffen hier , es etwas Liebe gehen zu zeigen , wenn Sie es nützlich finden!
Ich unterstütze alle Antworten im Zusammenhang mit einem Tool oder der Ausführung eines Lua-Ausdrucks.
Noch eine Option von meiner Seite:
In unseren Produktions- und Vorproduktionsdatenbanken befinden sich Tausende von Schlüsseln. Von Zeit zu Zeit müssen wir einige Schlüssel löschen (durch eine Maske), nach bestimmten Kriterien ändern usw. Natürlich gibt es keine Möglichkeit, dies manuell über die CLI zu tun, insbesondere mit Sharding (512 logische Datenbank in jeder physischen).
Zu diesem Zweck schreibe ich ein Java-Client-Tool, das all diese Arbeit erledigt. Im Falle des Löschens von Schlüsseln kann das Dienstprogramm sehr einfach sein, nur eine Klasse dort:
public class DataCleaner {
public static void main(String args[]) {
String keyPattern = args[0];
String host = args[1];
int port = Integer.valueOf(args[2]);
int dbIndex = Integer.valueOf(args[3]);
Jedis jedis = new Jedis(host, port);
int deletedKeysNumber = 0;
if(dbIndex >= 0){
deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, dbIndex);
} else {
int dbSize = Integer.valueOf(jedis.configGet("databases").get(1));
for(int i = 0; i < dbSize; i++){
deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, i);
}
}
if(deletedKeysNumber == 0) {
System.out.println("There is no keys with key pattern: " + keyPattern + " was found in database with host: " + host);
}
}
private static int deleteDataFromDB(Jedis jedis, String keyPattern, int dbIndex) {
jedis.select(dbIndex);
Set<String> keys = jedis.keys(keyPattern);
for(String key : keys){
jedis.del(key);
System.out.println("The key: " + key + " has been deleted from database index: " + dbIndex);
}
return keys.size();
}
}
Spring RedisTemplate selbst bietet die Funktionalität. RedissonClient in der neuesten Version hat die Funktion "deleteByPattern" nicht mehr unterstützt.
Ich habe den Redisson-Beispielcode aktualisiert. Ihr Code ist nicht wie Redisson atomar. Zwischen keysund deleteMethodenaufrufen können neue Schlüssel erscheinen .
Antworten:
Ab redis 2.6.0 können Sie lua-Skripte ausführen, die atomar ausgeführt werden. Ich habe noch nie einen geschrieben, aber ich denke, er würde ungefähr so aussehen
Siehe die EVAL-Dokumentation .
quelle
EVAL "local keys = redis.call('keys', ARGV[1]) \n for i=1,#keys,5000 do \n redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) \n end \n return keys" 0 prefix:*
del prefix:*
eine grundlegende Operation zu sein: /EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
In Bash ausführen:
AKTUALISIEREN
OK ich habe verstanden. Was ist mit dieser Methode: Speichern Sie das aktuelle zusätzliche inkrementelle Präfix und fügen Sie es allen Ihren Schlüsseln hinzu. Zum Beispiel:
Sie haben Werte wie diese:
Wenn Sie Daten löschen müssen, ändern Sie zuerst prefix_actuall (z. B. setzen Sie prefix_prefix_actuall = 3), damit Ihre Anwendung neue Daten in das Schlüsselpräfix 3: 1 und das Präfix 3: 2 schreibt. Dann können Sie sicher alte Werte aus Präfix: 2: 1 und Präfix: 2: 2 übernehmen und alte Schlüssel löschen.
quelle
redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Hier ist eine vollständig funktionierende und atomare Version eines in Lua implementierten Wildcard-Löschvorgangs. Es läuft viel schneller als die xargs-Version, da das Netzwerk viel weniger hin und her geht, und es ist vollständig atomar und blockiert alle anderen Anforderungen gegen Redis, bis es fertig ist. Wenn Sie Schlüssel in Redis 2.6.0 oder höher atomar löschen möchten, ist dies definitiv der richtige Weg:
Dies ist eine funktionierende Version von @ mcdizzles Idee in seiner Antwort auf diese Frage. Die Idee zu 100% geht an ihn.
BEARBEITEN: Laut Kikitos Kommentar unten tritt der Fehler "Zu viele Elemente zum Entpacken" auf , wenn Sie mehr Schlüssel zum Löschen als freien Speicher auf Ihrem Redis-Server haben . In diesem Fall tun Sie:
Wie Kikito vorgeschlagen hat.
quelle
for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
unpack
transformiert eine Tabelle in eine "Liste unabhängiger Variablen" (andere Sprachen nennen dasexplode
), aber die maximale Anzahl hängt nicht vom Systemspeicher ab. Es ist in Lua durch dieLUAI_MAXSTACK
Konstante festgelegt. In Lua 5.1 & LuaJIT sind es 8000 und in Lua 5.2 100000. Die Option for loop wird IMO empfohlen.EVAL
da sie die Schlüssel, mit denen sie arbeiten wird, nicht im Voraus angibt. Es sollte auf einer einzelnen Instanz funktionieren, aber erwarten Sie nicht, dass es mit Redis Cluster funktioniert.Haftungsausschluss: Die folgende Lösung bietet keine Atomizität.
Ab v2.8 bist du wirklich möchten den Befehl SCAN anstelle von KEYS [1] verwenden. Das folgende Bash-Skript demonstriert das Löschen von Schlüsseln nach Muster:
[1] KEYS ist ein gefährlicher Befehl, der möglicherweise zu einem DoS führen kann. Das Folgende ist ein Zitat aus der Dokumentationsseite:
UPDATE: Ein Einzeiler für den gleichen Grundeffekt -
quelle
-n 1
jedemredis-cli
Aufruf Folgendes hinzufügen :redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
Für diejenigen, die Probleme hatten, andere Antworten zu analysieren:
Ersetzen Sie
key:*:pattern
durch Ihr eigenes Muster und geben Sie dieses einredis-cli
und Sie können loslegen.Kredit lisco von: http://redis.io/commands/del
quelle
Ich benutze den folgenden Befehl in redis 3.2.8
Weitere Hilfe zur Suche nach Schlüsselmustern erhalten Sie hier: - https://redis.io/commands/keys . Verwenden Sie Ihr praktisches Muster im Glob-Stil gemäß Ihren Anforderungen wie
*YOUR_KEY_PREFIX*
oderYOUR_KEY_PREFIX??
oder andere.Und wenn einer von Ihnen die Redis PHP-Bibliothek integriert hat, hilft Ihnen die folgende Funktion.
Vielen Dank :)
quelle
Die Lösung von @ mcdizle funktioniert nicht, sondern nur für einen Eintrag.
Dieser funktioniert für alle Schlüssel mit demselben Präfix
Hinweis: Sie sollten 'Präfix' durch Ihr Schlüsselpräfix ersetzen ...
quelle
Mit diesem Befehl können Sie auch die Schlüssel löschen: -
Angenommen, Ihre Redis enthalten viele Arten von Schlüsseln.
Beispiel: ' xyz_category_fpc ' hier ist xyz ein Site-Name . Diese Schlüssel beziehen sich auf Produkte und Kategorien einer E-Commerce-Site und werden von FPC generiert.
Wenn Sie diesen Befehl wie folgt verwenden:
ODER
Es löscht alle Schlüssel wie ' xyz_category_fpc ' (lösche 1, 2 und 3 Schlüssel). Verwenden Sie zum Löschen anderer 4, 5 und 6 Zifferntasten ' xyz_product_fpc ' im obigen Befehl.
Wenn Sie alles in Redis löschen möchten , befolgen Sie diese Befehle.
Mit redis-cli:
Zum Beispiel: - in Ihrer Shell:
quelle
redis-cli del
ist nicht atomar.Wenn der Name der Schlüssel Leerzeichen enthält, können Sie dies in bash verwenden:
quelle
@ itamars Antwort ist großartig, aber das Parsen der Antwort hat bei mir nicht funktioniert, insb. in dem Fall, in dem in einem bestimmten Scan keine Schlüssel gefunden wurden. Eine möglicherweise einfachere Lösung direkt von der Konsole aus:
Dies verwendet auch SCAN, das KEYS in der Produktion vorzuziehen ist, aber nicht atomar ist.
quelle
Ich hatte gerade das gleiche Problem. Ich habe Sitzungsdaten für einen Benutzer im folgenden Format gespeichert:
Jeder Eintrag war also ein separates Schlüssel-Wert-Paar. Wenn die Sitzung zerstört wird, wollte ich alle Sitzungsdaten entfernen, indem ich Schlüssel mit dem Muster
session:sessionid:*
lösche - aber redis hat keine solche Funktion.Was ich getan habe: Speichern Sie die Sitzungsdaten in einem Hash . Ich schaffe nur einen Hash mit der Hash - ID von
session:sessionid
und dann schiebe ichkey-x
,key-y
,key-z
dass Hash (um mich nicht Sache tat) , und wenn ich nicht brauchen , dass Hash mehr ich nur zu tun ,DEL session:sessionid
und alle Daten mit der Hash - ID zugeordnet sind weg.DEL
ist atomar und der Zugriff auf Daten / das Schreiben von Daten in den Hash ist O (1).quelle
Ich denke, was Ihnen helfen könnte, ist MULTI / EXEC / DISCARD . Obwohl dies nicht zu 100% den Transaktionen entspricht , sollten Sie in der Lage sein, die Löschvorgänge von anderen Aktualisierungen zu isolieren.
quelle
Zu Ihrer Information.
redis-cli
keys
(dies verwendetscan
)Möglicherweise müssen Sie nur Großbuchstaben ändern.
scan-match.sh
clear-redis-key.sh
Führen Sie an der Bash-Eingabeaufforderung aus
quelle
Andere Antworten funktionieren möglicherweise nicht, wenn Ihr Schlüssel spezielle Zeichen enthält -
Guide$CLASSMETADATA][1]
zum Beispiel. Wenn Sie jeden Schlüssel in Anführungszeichen setzen, wird sichergestellt, dass er ordnungsgemäß gelöscht wird:quelle
Eine Version, die SCAN anstelle von KEYS (wie für Produktionsserver empfohlen) und
--pipe
nicht von xargs verwendet.Ich bevorzuge Pipe gegenüber Xargs, weil es effizienter ist und funktioniert, wenn Ihre Schlüssel Anführungszeichen oder andere Sonderzeichen enthalten, mit denen Ihre Shell versucht, sie zu interpretieren. Die Regex-Ersetzung in diesem Beispiel umschließt den Schlüssel in doppelte Anführungszeichen und entgeht allen doppelten Anführungszeichen.
quelle
Dies ist keine direkte Antwort auf die Frage, aber da ich bei der Suche nach meinen eigenen Antworten hierher gekommen bin, werde ich dies hier teilen.
Wenn Sie Dutzende oder Hunderte von Millionen von Schlüsseln haben, die Sie abgleichen müssen, führen die hier gegebenen Antworten dazu, dass Redis längere Zeit (Minuten?) Nicht reagiert und möglicherweise aufgrund des Speicherverbrauchs abstürzt (stellen Sie sicher, dass das Speichern im Hintergrund funktioniert) treten Sie mitten in Ihrer Operation ein).
Der folgende Ansatz ist zweifellos hässlich, aber ich habe keinen besseren gefunden. Atomarität kommt hier nicht in Frage. In diesem Fall besteht das Hauptziel darin, Redis 100% der Zeit auf dem Laufenden zu halten und zu reagieren. Es funktioniert perfekt, wenn Sie alle Schlüssel in einer der Datenbanken haben und kein Muster abgleichen müssen, aber http://redis.io/commands/FLUSHDB nicht verwenden können, da es die Natur blockiert.
Die Idee ist einfach: Schreiben Sie ein Skript, das in einer Schleife ausgeführt wird und eine O (1) -Operation wie http://redis.io/commands/SCAN oder http://redis.io/commands/RANDOMKEY verwendet , um Schlüssel abzurufen , und prüfen Sie, ob diese vorhanden sind Passen Sie das Muster an (falls erforderlich) und http://redis.io/commands/DEL nacheinander.
Wenn es einen besseren Weg gibt, lass es mich wissen, ich werde die Antwort aktualisieren.
Beispielimplementierung mit randomkey in Ruby als Rake-Task, ein nicht blockierender Ersatz für etwas wie
redis-cli -n 3 flushdb
:quelle
Es ist einfach über die Funktion "Zweig entfernen" in FastoRedis implementiert. Wählen Sie einfach den Zweig aus, den Sie entfernen möchten.
quelle
Bitte benutzen Sie diesen Befehl und versuchen Sie:
quelle
Ich habe die meisten der oben genannten Methoden ausprobiert, aber sie haben bei mir nicht funktioniert. Nach einigen Suchanfragen habe ich folgende Punkte gefunden:
-n [number]
del
aber wenn es Tausende oder Millionen von Schlüsseln sind , ist es besser zu nutzen ,unlink
weil unlink ist non-blocking , während del blockiert, für weitere Informationen besuchen Sie diese Seite unlink vs delkeys
sind wie del und blockiertAlso habe ich diesen Code verwendet, um Schlüssel nach Muster zu löschen:
quelle
Atommassenlöschung des armen Mannes?
Vielleicht könnten Sie sie alle so einstellen, dass sie in derselben Sekunde ablaufen - wie einige Minuten in der Zukunft - und dann bis zu diesem Zeitpunkt warten und sie alle gleichzeitig "selbstzerstörend" sehen.
aber ich bin mir nicht sicher, wie atomar das wäre.
quelle
Ab sofort können Sie einen Redis-Client verwenden und zuerst SCAN (unterstützt Pattern Matching) durchführen und dann jeden Schlüssel einzeln löschen.
Allerdings gibt es ein Problem auf der offiziellen redis GitHub einen Rüttler-Matching-del zu schaffen hier , es etwas Liebe gehen zu zeigen , wenn Sie es nützlich finden!
quelle
Ich unterstütze alle Antworten im Zusammenhang mit einem Tool oder der Ausführung eines Lua-Ausdrucks.
Noch eine Option von meiner Seite:
In unseren Produktions- und Vorproduktionsdatenbanken befinden sich Tausende von Schlüsseln. Von Zeit zu Zeit müssen wir einige Schlüssel löschen (durch eine Maske), nach bestimmten Kriterien ändern usw. Natürlich gibt es keine Möglichkeit, dies manuell über die CLI zu tun, insbesondere mit Sharding (512 logische Datenbank in jeder physischen).
Zu diesem Zweck schreibe ich ein Java-Client-Tool, das all diese Arbeit erledigt. Im Falle des Löschens von Schlüsseln kann das Dienstprogramm sehr einfach sein, nur eine Klasse dort:
quelle
Der folgende Befehl hat bei mir funktioniert.
quelle
Spring RedisTemplate selbst bietet die Funktionalität. RedissonClient in der neuesten Version hat die Funktion "deleteByPattern" nicht mehr unterstützt.
quelle
keys
unddelete
Methodenaufrufen können neue Schlüssel erscheinen .