Bagaimana menghapus kunci secara atomik yang cocok dengan suatu pola menggunakan Redis

576

Dalam Redis DB saya, saya memiliki sejumlah prefix:<numeric_id>hash.

Terkadang saya ingin membersihkan semuanya secara atom. Bagaimana saya melakukan ini tanpa menggunakan mekanisme penguncian terdistribusi?

Alexander Gladysh
sumber
Halo Steve, Ada beberapa masalah dengan situs web saya, saya telah menambahkannya ke blog saya yang lain mind-geek.net/nosql/redis/delete-keys-specific-expiry-time , Semoga ini bisa membantu.
Gaurav Tewari
43
Ini adalah skenario yang umum sehingga saya berharap tim Redis akan mempertimbangkan untuk menambahkan perintah asli untuknya.
Todd Menier
Saat ini Anda bisa melakukannya dengan Lua, lihat di bawah.
Alexander Gladysh
3
@ToddMenier Baru saja menyarankan, dapatkan alasan ini kembali untuk alasan mengapa hal itu tidak akan pernah terjadi: github.com/antirez/redis/issues/2042
Ray
1
Banyak orang mengajukan pertanyaan terkait tentang bagaimana menangani sejumlah besar kunci, kunci dengan karakter khusus, dll. Saya membuat pertanyaan terpisah karena kami mengalami masalah ini sekarang dan saya tidak berpikir jawabannya diposting pada pertanyaan ini. Berikut adalah pertanyaan lain: stackoverflow.com/questions/32890648/…
jakejgordon

Jawaban:

431

Dimulai dengan redis 2.6.0, Anda dapat menjalankan skrip lua, yang mengeksekusi secara atomis. Saya belum pernah menulis satu, tetapi saya pikir itu akan terlihat seperti ini

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

Peringatan : Seperti yang dikatakan dokumen Redis , karena masalah kinerja, keys perintah tidak boleh digunakan untuk operasi reguler dalam produksi, perintah ini dimaksudkan untuk debugging dan operasi khusus. Baca lebih banyak

Lihat dokumentasi EVAL .

mcdizzle
sumber
23
Catatan penting: ini gagal jika Anda memiliki lebih dari beberapa ribu kunci yang cocok dengan awalan.
Nathan Osman
93
Yang ini bekerja untuk sejumlah besar kunci: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
Aduh ... redis banyak digunakan sebagai cache kunci / toko sederhana. Ini tampaknya del prefix:* harus menjadi operasi mendasar: /
Ray
5
@Ray terus terang, jika Anda memerlukan fitur itu, Anda harus mempartisi data berdasarkan database atau server numetic, dan menggunakan flush / flushdb
Marc Gravell
9
Ya, gagal jika tidak ada kunci yang cocok dengan pola. Untuk memperbaikinya saya menambahkan kunci default:EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
manuelmhtr
706

Jalankan di bash:

redis-cli KEYS "prefix:*" | xargs redis-cli DEL

MEMPERBARUI

Baiklah saya mengerti. Bagaimana dengan cara ini: simpan awalan tambahan tambahan saat ini dan tambahkan ke semua kunci Anda. Sebagai contoh:

Anda memiliki nilai seperti ini:

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

Ketika Anda perlu membersihkan data, Anda mengubah prefix_actuall terlebih dahulu (misalnya mengatur prefix_prefix_actuall = 3), jadi aplikasi Anda akan menulis data baru ke awalan kunci: 3: 1 dan awalan: 3: 2. Kemudian Anda dapat dengan aman mengambil nilai-nilai lama dari awalan: 2: 1 dan awalan: 2: 2 dan membersihkan kunci-kunci lama.

Casey
sumber
14
Maaf, ini bukan penghapusan atom. Seseorang dapat menambahkan kunci baru antara tombol dan DEL. Saya tidak ingin menghapusnya.
Alexander Gladysh
36
Kunci, yang akan dibuat setelah perintah KEYS tidak akan dihapus.
Casey
6
Saya hanya perlu menghapus beberapa kunci buruk, jadi jawaban pertama Casey tepat, kecuali saya harus memindahkan kunci di luar tanda kutip: redis-cli KEYS "awalan: *" | xargs redis-cli DEL
jslatts
19
Jawaban pertama juga membantu saya. Varian lain jika kunci redis Anda mengandung tanda kutip atau karakter lain yang mengacaukan xargs:redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
overthink
18
Jika Anda memiliki database multible (keyspaces) maka ini caranya: Katakanlah Anda perlu menghapus kunci di db3:redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Christoffer
73

Berikut ini adalah versi yang sepenuhnya berfungsi dan atom dari penghapusan wildcard diimplementasikan di Lua. Itu akan berjalan jauh lebih cepat daripada versi xargs karena jauh lebih sedikit jaringan bolak-balik, dan itu benar-benar atomik, memblokir permintaan lain terhadap redis sampai selesai. Jika Anda ingin menghapus kunci secara atomis pada Redis 2.6.0 atau lebih tinggi, ini jelas cara yang harus dilakukan:

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

Ini adalah versi kerja dari ide @ mcdizzle dalam jawabannya untuk pertanyaan ini. Penghargaan untuk ide 100% jatuh padanya.

EDIT: Per komentar Kikito di bawah ini, jika Anda memiliki lebih banyak kunci untuk dihapus daripada membebaskan memori di server Redis Anda, Anda akan mengalami kesalahan "terlalu banyak elemen untuk dibuka" . Dalam hal ini, lakukan:

for _,k in ipairs(redis.call('keys', ARGV[1])) do 
    redis.call('del', k) 
end

Seperti yang disarankan Kikito.

Eli
sumber
10
Kode di atas akan muncul jika Anda memiliki sejumlah kunci (kesalahannya adalah "terlalu banyak elemen untuk dibuka"). Saya sarankan menggunakan loop pada bagian Lua:for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
kikito
@kikito, ya, jika lua tidak dapat menumbuhkan tumpukan ke jumlah kunci yang ingin Anda hapus (kemungkinan besar karena kurangnya memori), Anda harus melakukannya dengan for for loop. Saya tidak akan merekomendasikan melakukan ini kecuali Anda harus melakukannya.
Eli
1
Lua unpackmengubah tabel dalam "daftar variabel independen" (bahasa lain menyebutnya explode) tetapi jumlah maks tidak bergantung pada memori sistem; itu tetap di lua melalui LUAI_MAXSTACKkonstanta. Dalam Lua 5.1 & LuaJIT itu 8000 dan di Lua 5.2 adalah 100000. Opsi untuk loop direkomendasikan IMO.
kikito
1
Perlu dicatat bahwa lua scripting hanya tersedia dari Redis 2.6 ke atas
wallacer
1
Setiap solusi berbasis Lua akan melanggar semantik EVALkarena tidak menentukan terlebih dahulu kunci yang akan dioperasikan. Itu harus bekerja pada satu contoh tetapi jangan berharap itu bekerja dengan Redis Cluster.
Kevin Christopher Henry
67

Penafian: solusi berikut ini tidak memberikan atomicity.

Dimulai dengan v2.8 Anda benar - benar ingin menggunakan perintah SCAN, bukan KEYS [1]. Skrip Bash berikut menunjukkan penghapusan kunci berdasarkan pola:

#!/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 adalah perintah berbahaya yang berpotensi menghasilkan DoS. Berikut ini adalah kutipan dari halaman dokumentasinya:

Peringatan: pertimbangkan KUNCI sebagai perintah yang seharusnya hanya digunakan di lingkungan produksi dengan sangat hati-hati. Ini dapat merusak kinerja ketika dieksekusi terhadap database besar. Perintah ini dimaksudkan untuk debugging dan operasi khusus, seperti mengubah tata letak keyspace Anda. Jangan gunakan KUNCI dalam kode aplikasi reguler Anda. Jika Anda mencari cara untuk menemukan kunci di subset dari ruang kunci Anda, pertimbangkan untuk menggunakan set.

UPDATE: satu liner untuk efek dasar yang sama -

$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL
Itamar Haber
sumber
9
Namun demikian, menghindari KEYS jelas merupakan praktik terbaik, jadi ini adalah solusi hebat di mana pun penghapusan non-atomik dimungkinkan.
fatal_error
Ini bekerja untuk saya; Namun, kunci saya kebetulan ada di database 1. Jadi saya harus menambahkan -n 1ke setiap redis-clidoa:redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
Rob Johansen
Perhatikan bahwa ini tidak berfungsi jika kunci Anda mengandung karakter khusus
mr1031011
Temuan yang menarik dan berharga ... Saya ingin tahu apakah ada cara untuk mengutip hal-hal untuk xargs ...
Itamar Haber
apa yang dilakukan -L 100 ??
Aparna
41

Bagi mereka yang kesulitan menguraikan jawaban lain:

eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0

Ganti key:*:patterndengan pola Anda sendiri dan masukkan ini ke dalam redis-clidan Anda baik untuk pergi.

Credit lisco dari: http://redis.io/commands/del

Randomor
sumber
37

Saya menggunakan perintah di bawah ini dalam redis 3.2.8

redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL

Anda dapat memperoleh bantuan lebih lanjut terkait dengan pencarian pola kunci dari sini: - https://redis.io/commands/keys . Gunakan pola gabus nyaman Anda sesuai kebutuhan Anda suka *YOUR_KEY_PREFIX*atau YOUR_KEY_PREFIX??atau yang lain.

Dan jika ada di antara Anda memiliki perpustakaan PHP Redis terintegrasi daripada fungsi di bawah ini akan membantu Anda.

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

Terima kasih :)

Yashrajsinh Jadeja
sumber
23

Solusi @ mcdizle tidak berfungsi, hanya berfungsi untuk satu entri.

Ini berfungsi untuk semua kunci dengan awalan yang sama

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

Catatan: Anda harus mengganti 'awalan' dengan awalan kunci Anda ...

efaruk
sumber
2
menggunakan lua adalah loooooot lebih cepat daripada menggunakan xargs, dalam urutan ke 10 ^ 4.
deepak
22

Anda juga dapat menggunakan perintah ini untuk menghapus kunci: -

Misalkan ada banyak jenis kunci di redis Anda seperti-

  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'

Ex- ' xyz_category_fpc ' di sini xyz adalah nama samaran , dan kunci-kunci ini terkait dengan produk dan kategori situs E-Commerce dan dihasilkan oleh FPC.

Jika Anda menggunakan perintah ini sebagai berikut-

redis-cli --scan --pattern 'key*' | xargs redis-cli del

ATAU

redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del

Ini menghapus semua kunci seperti ' xyz_category_fpc ' (hapus kunci 1, 2 dan 3). Untuk menghapus kunci angka 4, 5 dan 6 lainnya gunakan ' xyz_product_fpc ' dalam perintah di atas.

Jika Anda ingin Hapus Semuanya di Redis , maka ikuti Perintah ini-

Dengan redis-cli:

  1. FLUSHDB - Menghapus data dari basis data CURRENT koneksi Anda.
  2. FLUSHALL - Menghapus data dari SEMUA basis data.

Misalnya: - di shell Anda:

redis-cli flushall
redis-cli flushdb
Vishal Thakur
sumber
3
Terima kasih, tetapi keluaran pipa ke redis-cli deltidak atomik.
Alexander Gladysh
13

Jika Anda memiliki ruang dalam nama kunci, Anda dapat menggunakan ini di bash:

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

@ itamar jawabannya bagus, tapi penguraian balasannya tidak bekerja untuk saya, esp. dalam kasus di mana tidak ada kunci yang ditemukan dalam pemindaian yang diberikan. Solusi yang mungkin lebih sederhana, langsung dari konsol:

redis-cli -h HOST -p PORT  --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL

Ini juga menggunakan SCAN, yang lebih disukai daripada KEYS dalam produksi, tetapi tidak atomik.

Guitan
sumber
8

Saya hanya punya masalah yang sama. Saya menyimpan data sesi untuk pengguna dalam format:

session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z

Jadi, setiap entri adalah pasangan kunci-nilai yang terpisah. Ketika sesi dihancurkan, saya ingin menghapus semua data sesi dengan menghapus kunci dengan pola session:sessionid:*- tetapi redis tidak memiliki fungsi seperti itu.

Apa yang saya lakukan: menyimpan data sesi dalam hash . Saya cukup membuat hash dengan id hash dari session:sessioniddan kemudian saya mendorong key-x, key-y, key-zdi hash itu (agar tidak peduli dengan saya) dan jika saya tidak perlu bahwa hash lagi saya hanya melakukan DEL session:sessioniddan semua data yang terkait dengan hash id hilang. DELadalah atom dan mengakses data / menulis data ke hash adalah O (1).

Maks
sumber
Solusi yang bagus, tetapi nilai-nilai saya adalah hash sendiri. Dan Redis menyimpan hash di dalam hash lainnya.
Alexander Gladysh
3
Namun, bidang dalam hash tidak memiliki fungsionalitas kedaluwarsa, yang terkadang sangat berguna.
Evi Song
bagi saya ini adalah jawaban terbersih / paling sederhana sejauh ini
Sebastien H.
Bukankah satu set lebih masuk akal?
Jack Tuck
5

Saya pikir yang mungkin bisa membantu Anda adalah MULTI / EXEC / DISCARD . Meskipun tidak 100% setara dengan transaksi , Anda harus dapat mengisolasi penghapusan dari pembaruan lain.

alexpopescu
sumber
4
Tapi saya tidak tahu bagaimana menggunakannya di sini. DEL adalah atom dengan sendirinya (atau jadi saya pikir). Dan saya tidak bisa mendapatkan nilai dari tombol sampai saya melakukan EXEC, jadi saya tidak bisa menggunakan tombol dan DEL di MULTI yang sama.
Alexander Gladysh
5

FYI.

  • hanya menggunakan bash dan redis-cli
  • tidak menggunakan keys(ini menggunakan scan)
  • berfungsi dengan baik dalam mode cluster
  • bukan atom

Mungkin Anda hanya perlu memodifikasi huruf kapital.

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

Jalankan di bash prompt

$ ./clear-redis-key.sh key_head_pattern
plhn
sumber
5

Jawaban lain mungkin tidak berfungsi jika kunci Anda berisi karakter khusus - Guide$CLASSMETADATA][1]misalnya. Memasukkan setiap kunci ke dalam tanda kutip akan memastikan mereka dihapus dengan benar:

redis-cli --scan --pattern sf_* | awk '{print $1}' | sed "s/^/'/;s/$/'/" | xargs redis-cli del
Quentin S.
sumber
2
Script ini berfungsi sempurna, diuji dengan lebih dari 25000 kunci.
Jordi
1
Anda juga dapat menambahkan tanda kutip tunggal dalam awk menggunakan ungkapan lucu ini `awk '{print"' "'"' "$ 1" '"'" '"}'`
Roberto Congiu
3

Versi menggunakan SCAN daripada KEYS (seperti yang direkomendasikan untuk server produksi) dan --pipebukan xargs.

Saya lebih suka menggunakan pipa lebih dari xargs karena lebih efisien dan berfungsi ketika kunci Anda berisi tanda kutip atau karakter khusus lain yang Anda coba coba dan tafsirkan. Substitusi pengganti dalam contoh ini membungkus kunci dalam tanda kutip ganda, dan lolos dari tanda kutip ganda di dalamnya.

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
tekumara
sumber
Solusi ini bekerja dengan baik untuk saya bahkan pada tombol sekitar 7m!
Danny
2

Ini bukan jawaban langsung untuk pertanyaan itu, tetapi karena saya tiba di sini ketika mencari jawaban saya sendiri, saya akan membagikan ini di sini.

Jika Anda memiliki puluhan atau ratusan juta kunci yang harus Anda cocokkan, jawaban yang diberikan di sini akan menyebabkan Redis menjadi tidak responsif untuk jumlah waktu yang signifikan (menit?), Dan berpotensi crash karena konsumsi memori (pastikan, penyimpanan latar belakang akan tendang di tengah operasi Anda).

Pendekatan berikut tidak bisa disangkal jelek, tapi saya tidak menemukan yang lebih baik. Atomicity tidak dipertanyakan di sini, dalam hal ini tujuan utama adalah menjaga Redis tetap responsif dan 100% dari waktu. Ini akan berfungsi dengan baik jika Anda memiliki semua kunci di salah satu basis data dan Anda tidak perlu mencocokkan pola apa pun, tetapi tidak dapat menggunakan http://redis.io/commands/FLUSHDB karena itu memblokir alam.

Gagasannya sederhana: tulis skrip yang berjalan dalam satu lingkaran dan gunakan operasi O (1) seperti http://redis.io/commands/SCAN atau http://redis.io/commands/RANDOMKEY untuk mendapatkan kunci, periksa apakah mereka cocokkan polanya (jika Anda membutuhkannya) dan http://redis.io/commands/DEL satu per satu.

Jika ada cara yang lebih baik untuk melakukannya, beri tahu saya, saya akan memperbarui jawabannya.

Contoh implementasi dengan kunci acak di Ruby, sebagai tugas menyapu, pengganti non memblokir sesuatu seperti 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
Spajus
sumber
2

Ini sederhana diimplementasikan melalui fungsi "Hapus cabang" di FastoRedis , cukup pilih cabang yang ingin Anda hapus.

masukkan deskripsi gambar di sini

Topilski Alexandr
sumber
Apakah ini dilakukan secara atom? Dan bagaimana ini membantu melakukannya dalam kode ?
Matius Baca
2

Silakan gunakan perintah ini dan coba:

redis-cli --raw keys "$PATTERN" | xargs redis-cli del
Suf_Malek
sumber
Bukan atom, dan menduplikasi jawaban lain.
Matius Baca
1

Saya mencoba sebagian besar metode yang disebutkan di atas, tetapi mereka tidak berhasil bagi saya, setelah beberapa pencarian saya menemukan poin-poin ini:

  • jika Anda memiliki lebih dari satu db pada redis, Anda harus menentukan basis datanya -n [number]
  • jika Anda memiliki beberapa tombol yang digunakan deltetapi jika ada ribuan atau jutaan kunci lebih baik digunakan unlinkkarena pembatalan tautan adalah pemblokiran sementara del memblokir, untuk informasi lebih lanjut kunjungi halaman ini pembatalan tautan vs del
  • juga keysseperti del dan memblokir

jadi saya menggunakan kode ini untuk menghapus kunci berdasarkan pola:

 redis-cli -n 2 --scan --pattern '[your pattern]' | xargs redis-cli -n 2 unlink 
mahdi yousefi
sumber
0

penghapusan massa atom orang miskin?

mungkin Anda bisa mengatur semuanya menjadi EXPIREAT pada detik yang sama - seperti beberapa menit di masa mendatang - dan kemudian menunggu hingga waktu itu dan melihat semuanya "merusak diri sendiri" pada saat yang sama.

tapi saya tidak begitu yakin bagaimana atomnya itu.

Chris
sumber
0

Iklan sekarang, Anda dapat menggunakan klien redis dan melakukan SCAN pertama (mendukung pencocokan pola) dan kemudian DEL setiap tombol secara individual.

Namun, ada masalah pada redis github resmi untuk membuat derai-pencocokan-del di sini , tunjukkan padanya beberapa cinta jika Anda merasa berguna!

Asalle
sumber
-1

Saya mendukung semua jawaban yang terkait dengan memiliki beberapa alat atau menjalankan ekspresi Lua.

Satu lagi opsi dari sisi saya:

Dalam basis data produksi dan pra-produksi kami ada ribuan kunci. Dari waktu ke waktu kita perlu menghapus beberapa kunci (dengan beberapa mask), memodifikasi dengan beberapa kriteria dll. Tentu saja, tidak ada cara untuk melakukannya secara manual dari CLI, terutama yang memiliki sharding (512 dbs logis dalam setiap fisik).

Untuk tujuan ini saya menulis alat klien java yang melakukan semua pekerjaan ini. Dalam kasus penghapusan kunci utilitas bisa sangat sederhana, hanya satu kelas di sana:

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

}
Denys
sumber
-1

Perintah di bawah ini bekerja untuk saya.

redis-cli -h redis_host_url KEYS "*abcd*" | xargs redis-cli -h redis_host_url DEL
Sumit Saurabh
sumber
-3

Spring RedisTemplate sendiri menyediakan fungsionalitas. RedissonClient dalam versi terbaru telah mencabut fungsi "deleteByPattern".

Set<String> keys = redisTemplate.keys("geotag|*");
redisTemplate.delete(keys);
Arijeet Saha
sumber
2
Saya memperbarui kode sampel Redisson. Kode Anda tidak dalam pendekatan atom seperti yang dilakukan Redisson. Ada beberapa kunci baru yang dapat muncul di antara metode keysdan deletepemanggilan.
Nikita Koksharov