So löschen Sie atomar Schlüssel, die einem Muster entsprechen, mit Redis


576

In meiner Redis DB habe ich eine Reihe von prefix:<numeric_id>Hashes.

Manchmal möchte ich sie alle atomar reinigen. Wie mache ich das, ohne einen verteilten Verriegelungsmechanismus zu verwenden?


Hallo Steve, es gibt ein Problem mit meiner Website. Ich habe es meinem anderen Blog mind-geek.net/nosql/redis/delete-keys-specific-expiry-time hinzugefügt. Ich hoffe , das hilft.
Gaurav Tewari

43
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

EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]

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

Siehe die EVAL-Dokumentation .


23
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:

Sie haben Werte wie diese:

prefix_prefix_actuall = 2
prefix:2:1 = 4
prefix:2:2 = 10

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.


14
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:

redis-cli -n [some_db] -h [some_host_name] EVAL "return redis.call('DEL', unpack(redis.call('KEYS', ARGV[1] .. '*')))" 0 prefix:

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

Wie Kikito vorgeschlagen hat.


10
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 -

$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL

9
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.

Kredit lisco von: http://redis.io/commands/del


37

Ich benutze den folgenden Befehl in redis 3.2.8

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

Vielen Dank :)


23

Die Lösung von @ mcdizle funktioniert nicht, sondern nur für einen Eintrag.

Dieser funktioniert für alle Schlüssel mit demselben Präfix

EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*

Hinweis: Sie sollten 'Präfix' durch Ihr Schlüsselpräfix ersetzen ...


2
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.

  1. 'xyz_category_fpc_12'
  2. 'xyz_category_fpc_245'
  3. 'xyz_category_fpc_321'
  4. 'xyz_product_fpc_876'
  5. 'xyz_product_fpc_302'
  6. '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:

  1. FLUSHDB - Entfernt Daten aus der CURRENT-Datenbank Ihrer Verbindung.
  2. FLUSHALL - Entfernt Daten aus ALLEN Datenbanken.

Zum Beispiel: - in Ihrer Shell:

redis-cli flushall
redis-cli flushdb

3
Vielen Dank, aber die Weiterleitung redis-cli delist nicht atomar.
Alexander Gladysh

13

Wenn der Name der Schlüssel Leerzeichen enthält, können Sie dies in bash verwenden:

redis-cli keys "pattern: *" | xargs -L1 -I '$' echo '"$"' | xargs redis-cli del

10

@ 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.


8

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).


Gute Lösung, aber meine Werte sind selbst Hashes. Und Redis speichert Hash in einem anderen Hash.
Alexander Gladysh

3
Den Feldern in einem Hash fehlt jedoch die Ablauffunktion, was manchmal sehr nützlich ist.
Evi Song

Für mich ist dies die bisher sauberste / einfachste Antwort
Sebastien H.

Ist ein Set nicht sinnvoller?
Jack Tuck

5

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.


4
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

Führen Sie an der Bash-Eingabeaufforderung aus

$ ./clear-redis-key.sh key_head_pattern

5

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

2
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.

export REDIS_HOST=your.hostname.com
redis-cli -h "$REDIS_HOST" --scan --pattern "YourPattern*" > /tmp/keys
time cat /tmp/keys | perl -pe 's/"/\\"/g;s/^/DEL "/;s/$/"/;'  | redis-cli -h "$REDIS_HOST" --pipe

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.

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:

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


2

Bitte benutzen Sie diesen Befehl und versuchen Sie:

redis-cli --raw keys "$PATTERN" | xargs redis-cli del

Nicht atomar und dupliziert andere Antworten.
Matthew Read

1

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:

 redis-cli -n 2 --scan --pattern '[your pattern]' | xargs redis-cli -n 2 unlink 

0

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.


0

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!


-1

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

}

-1

Der folgende Befehl hat bei mir funktioniert.

redis-cli -h redis_host_url KEYS "*abcd*" | xargs redis-cli -h redis_host_url DEL

-3

Spring RedisTemplate selbst bietet die Funktionalität. RedissonClient in der neuesten Version hat die Funktion "deleteByPattern" nicht mehr unterstützt.

Set<String> keys = redisTemplate.keys("geotag|*");
redisTemplate.delete(keys);

2
Ich habe den Redisson-Beispielcode aktualisiert. Ihr Code ist nicht wie Redisson atomar. Zwischen keysund deleteMethodenaufrufen können neue Schlüssel erscheinen .
Nikita Koksharov
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.