Muitas pessoas fizeram perguntas relacionadas a como lidar com um grande número de chaves, chaves com caracteres especiais, etc. Criei uma pergunta separada, pois estamos tendo esse problema agora e não acho que a resposta seja publicada. Aqui é a outra pergunta: stackoverflow.com/questions/32890648/...
jakejgordon
Respostas:
431
A partir do redis 2.6.0, você pode executar scripts lua, que são executados atomicamente. Eu nunca escrevi um, mas acho que seria algo como isto
Aviso : Como o documento Redis diz, por causa dos indicadores de desempenho, o keys
comando não deve ser usado para operações regulares na produção, este comando é destinado à depuração e operações especiais. consulte Mais informação
Nota importante: isso falhará se você tiver mais de duas mil chaves correspondentes ao prefixo.
Nathan Osman
93
Este está trabalhando para um grande número de chaves: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 19/08/14
181
Ai ... redis é muito usado como cache simples de chave / armazenamento. Esta parece del prefix:* ser uma operação fundamental: /
Ray
5
@Ray francamente, se você precisa que o recurso que você deve simplesmente dividir os dados por banco de dados numetic ou servidor e uso nivelado / flushdb
Marc Gravell
9
Sim, falha se nenhuma chave corresponder ao padrão. Para corrigir isso, adicionei uma chave padrão:EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
manuelmhtr 1/16/16
706
Executar no bash:
redis-cli KEYS "prefix:*" | xargs redis-cli DEL
ATUALIZAR
OK eu entendi. E quanto a isso: armazene o prefixo incremental adicional atual e adicione-o a todas as suas chaves. Por exemplo:
Quando você precisar limpar os dados, altere o prefixo_actuall primeiro (por exemplo, defina prefix_prefix_actuall = 3), para que seu aplicativo grave novos dados nos prefixos de chaves: 3: 1 e prefixo: 3: 2. Em seguida, você pode pegar valores antigos com segurança do prefixo: 2: 1 e prefixo: 2: 2 e limpar as chaves antigas.
Desculpe, mas isso não é exclusão atômica. Alguém pode adicionar novas chaves entre KEYS e DEL. Eu não quero excluir aqueles.
Alexander Gladysh 24/10/10
36
As chaves que serão criadas após o comando KEYS não serão excluídas.
Casey
6
Eu só precisava limpar algumas teclas ruins, então a primeira resposta de Casey foi imediata, exceto que eu tive que mover as teclas para fora das aspas: redis-cli KEYS "prefix: *" | xargs redis-cli DEL
jslatts
19
A primeira resposta também me ajudou. Outra variante se as teclas redis contiverem aspas ou outros caracteres que bagunçam o xargs:redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
overthink
18
Se você tem bancos de dados multible (keyspaces) então este é o truque: Vamos dizer que você precisa para chaves de exclusão em db3:redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Christoffer
73
Aqui está uma versão completamente funcional e atômica de uma exclusão curinga implementada em Lua. Ele rodará muito mais rápido que a versão xargs devido a muito menos retorno e retorno da rede, e é completamente atômico, bloqueando outras solicitações contra o redis até que seja concluído. Se você deseja excluir atomicamente chaves no Redis 2.6.0 ou superior, este é definitivamente o caminho a seguir:
Esta é uma versão funcional da idéia de @ mcdizzle em sua resposta a esta pergunta. O crédito pela ideia 100% vai para ele.
EDIT: Pelo comentário de Kikito abaixo, se você tiver mais chaves para excluir do que memória livre no servidor Redis, encontrará o erro "muitos elementos para descompactar" . Nesse caso, faça:
for _,k in ipairs(redis.call('keys', ARGV[1])) do
redis.call('del', k)
end
O código acima será exibido se você tiver um número significativo de chaves (o erro é "muitos elementos para descompactar"). Eu recomendo usar um laço na parte Lua:for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
Kikito
@kikito, sim, se lua não puder aumentar a pilha para o número de chaves que você deseja excluir (provavelmente devido à falta de memória), será necessário fazê-lo com um loop for. Eu não recomendaria fazer isso, a menos que você precise.
Eli
1
Lua unpacktransforma uma tabela em uma "lista de variáveis independentes" (outras línguas chamam isso explode), mas o número máximo não depende da memória do sistema; é fixado em lua através da LUAI_MAXSTACKconstante. No Lua 5.1 e LuaJIT é 8000 e no Lua 5.2 é 100000. A opção for loop é recomendada IMO.
Kikito
1
É importante notar que scripting lua só está disponível na Redis 2,6-se
wallacer
1
Qualquer solução baseada em Lua violará a semântica, EVALpois não especifica antecipadamente as chaves nas quais irá operar. Ele deve funcionar em uma única instância, mas não espere que funcione com o Redis Cluster.
Kevin Christopher Henry
67
Isenção de responsabilidade: a solução a seguir não fornece atomicidade.
A partir da v2.8, você realmente deseja usar o comando DIGITALIZAR em vez de KEYS [1]. O script Bash a seguir demonstra a exclusão de chaves por padrão:
#!/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 é um comando perigoso que pode resultar potencialmente em um DoS. A seguir, uma citação de sua página de documentação:
Aviso: considere KEYS como um comando que deve ser usado apenas em ambientes de produção com extremo cuidado. Isso pode prejudicar o desempenho quando executado em bancos de dados grandes. Este comando destina-se à depuração e operações especiais, como alterar o layout do espaço da chave. Não use KEYS no seu código de aplicativo normal. Se você estiver procurando uma maneira de encontrar chaves em um subconjunto do seu espaço de chaves, considere usar conjuntos.
No entanto, evitar KEYS é definitivamente considerado uma prática recomendada, portanto, essa é uma ótima solução sempre que possíveis exclusões não atômicas.
fatal_error
Isso funcionou para mim; no entanto, minhas chaves passou a ser na base de dados 1. Então, eu tive que adicionar -n 1a cada redis-cliinvocação:redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
Rob Johansen
Observe que isso não funciona se suas chaves contiverem caracteres especiais
mr1031011 14/11
Achado interessante e valioso ... Gostaria de saber se há uma maneira de citar as coisas para xargs ...
Itamar Haber
o que -L 100 faz?
Aparna
41
Para aqueles que estavam tendo problemas para analisar outras respostas:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
Substitua key:*:patternpor seu próprio padrão e insira isso redis-clie você estará pronto.
redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL
Você pode obter mais ajuda relacionada à pesquisa de padrões de chaves aqui: - https://redis.io/commands/keys . Use o seu padrão de estilo glob conveniente como por sua exigência como *YOUR_KEY_PREFIX*ou YOUR_KEY_PREFIX??ou qualquer outro.
E se algum de vocês tiver integrado a biblioteca Redis PHP, a função abaixo o ajudará.
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);
}
}
usar lua é muito mais rápido que usar xargs, na ordem de 10 ^ 4.
Deepak
22
Você também pode usar este comando para excluir as chaves: -
Suponha que haja muitos tipos de chaves nos seus redis, como
'xyz_category_fpc_12'
'xyz_category_fpc_245'
'xyz_category_fpc_321'
'xyz_product_fpc_876'
'xyz_product_fpc_302'
'xyz_product_fpc_01232'
Ex- ' xyz_category_fpc ' aqui xyz é um nome de site e essas chaves estão relacionadas a produtos e categorias de um site de comércio eletrônico e geradas pelo FPC.
Se você usar este comando como abaixo
redis-cli --scan --pattern 'key*' | xargs redis-cli del
OU
redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del
Exclui todas as chaves como ' xyz_category_fpc ' (exclua as teclas 1, 2 e 3). Para excluir outras teclas numéricas 4, 5 e 6, use ' xyz_product_fpc ' no comando acima.
Se você deseja excluir tudo no Redis , siga estes comandos
Com redis-cli:
FLUSHDB - Remove os dados do banco de dados ATUAL da sua conexão.
FLUSHALL - Remove dados de TODOS os bancos de dados.
A resposta de @ itamar é ótima, mas a análise da resposta não estava funcionando para mim, esp. no caso em que não há chaves encontradas em uma determinada varredura. Uma solução possivelmente mais simples, diretamente do console:
redis-cli -h HOST -p PORT --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL
Isso também usa SCAN, que é preferível a KEYS na produção, mas não é atômico.
Eu apenas tive o mesmo problema. Eu armazenei os dados da sessão para um usuário no formato:
session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z
Portanto, cada entrada era um par de valores-chave separado. Quando a sessão é destruída, eu queria remover todos os dados da sessão excluindo chaves com o padrão session:sessionid:*- mas o redis não possui essa função.
O que eu fiz: armazene os dados da sessão em um hash . Eu só criar um hash com a ID de hash session:sessionide então eu empurrar key-x, key-y, key-zem que de hash (ordem não importa para mim) e se eu não preciso esse hash mais Eu só faço um DEL session:sessionide todos os dados associados a esse ID de hash é ido. DELé atômico e o acesso aos dados / gravação de dados no hash é O (1).
Mas não consigo descobrir como usá-los aqui. DEL é atômico por si só (ou assim eu acho). E não consigo obter valores de KEYS até executar EXEC; portanto, não posso usar KEYS e DEL no mesmo MULTI.
Alexander Gladysh 24/10/10
5
PARA SUA INFORMAÇÃO.
usando apenas bash e redis-cli
não usando keys(isso usa scan)
funciona bem no modo de cluster
não atômico
Talvez você precise modificar apenas caracteres maiúsculos.
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
Outras respostas podem não funcionar se sua chave contiver caracteres especiais - Guide$CLASSMETADATA][1]por exemplo. A quebra de cada chave entre aspas garantirá que elas sejam excluídas corretamente:
redis-cli --scan --pattern sf_*| awk '{print $1}'| sed "s/^/'/;s/$/'/"| xargs redis-cli del
Esse script funciona perfeitamente, testado com mais de 25000 chaves.
Jordi
1
Você também pode adicionar aspas simples no awk usando esta expressão engraçada `awk '{print"' "'"' "$ 1" '"'" '}}' `
Roberto Congiu
3
Uma versão que usa SCAN em vez de KEYS (como recomendado para servidores de produção) e em --pipevez de xargs.
Prefiro canalizar sobre xargs porque é mais eficiente e funciona quando suas chaves contêm aspas ou outros caracteres especiais que seu shell tenta e interpreta. A substituição de expressão regular neste exemplo envolve a chave entre aspas duplas e escapa as aspas duplas dentro.
Esta solução funcionou bem para mim, mesmo em teclas de aproximadamente 7 m!
Danny
2
Esta não é uma resposta direta à pergunta, mas como cheguei aqui ao procurar minhas próprias respostas, vou compartilhar isso aqui.
Se você tiver dezenas ou centenas de milhões de chaves com as quais corresponder, as respostas fornecidas aqui farão com que os Redis não respondam por um período significativo de tempo (minutos?) E potencialmente falhem devido ao consumo de memória (certifique-se de que o salvamento em segundo plano será chute no meio de sua operação).
A abordagem a seguir é inegavelmente feia, mas não encontrei uma melhor. A atomicidade está fora de questão aqui, neste caso, o principal objetivo é manter o Redis ativo e responsivo 100% do tempo. Funcionará perfeitamente se você tiver todas as suas chaves em um dos bancos de dados e não precisar corresponder a nenhum padrão, mas não puder usar http://redis.io/commands/FLUSHDB por causa de sua natureza bloqueadora.
Se houver uma maneira melhor de fazer isso, entre em contato, atualizarei a resposta.
Exemplo de implementação com randomkey no Ruby, como uma tarefa rake, um substituto não-bloqueador de algo como 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
Eu tentei a maioria dos métodos mencionados acima, mas eles não funcionaram para mim, depois de algumas pesquisas, encontrei estes pontos:
se você tiver mais de um banco de dados no redis, determine o banco de dados usando -n [number]
se você usa algumas chaves, delmas se existem milhares ou milhões de chaves, é melhor usar unlinkporque o desvincular não está bloqueando enquanto o del está bloqueando, para obter mais informações, visite esta página unlink vs del
também keyssão como del e está bloqueando
então usei esse código para excluir chaves por padrão:
talvez você possa configurá-los para EXPIREAT no mesmo segundo - como alguns minutos no futuro - e esperar até esse momento e vê-los todos "se autodestruir" ao mesmo tempo.
mas não tenho muita certeza de quão atômica isso seria.
Agora, você pode usar um cliente redis e executar a primeira DIGITALIZAÇÃO (suporta a correspondência de padrões) e, em seguida, DEL cada tecla individualmente.
No entanto, existe um problema no redis github oficial para criar um delineador de correspondência de patter aqui , mostre-lhe um pouco de amor se achar útil!
Eu apoio todas as respostas relacionadas a ter alguma ferramenta ou executar a expressão Lua.
Mais uma opção do meu lado:
Nos nossos bancos de dados de produção e pré-produção, existem milhares de chaves. Ocasionalmente, precisamos excluir algumas chaves (por alguma máscara), modificar por alguns critérios etc. É claro que não há como fazê-lo manualmente a partir da CLI, principalmente com sharding (512 dbs lógicos em cada físico).
Para esse propósito, escrevo a ferramenta cliente java que faz todo esse trabalho. No caso de exclusão de chaves, o utilitário pode ser muito simples, apenas uma classe:
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();
}
}
O Spring RedisTemplate propriamente dito fornece a funcionalidade. O RedissonClient na versão mais recente descontinuou a funcionalidade "deleteByPattern".
Eu atualizei o código de exemplo Redisson. Seu código não está em uma abordagem atômica como Redisson. Existem novas chaves que podem aparecer entre os métodos keyse deleteinvocações.
Respostas:
A partir do redis 2.6.0, você pode executar scripts lua, que são executados atomicamente. Eu nunca escrevi um, mas acho que seria algo como isto
Veja a documentação do EVAL .
fonte
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:*
ser uma operação fundamental: /EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
Executar no bash:
ATUALIZAR
OK eu entendi. E quanto a isso: armazene o prefixo incremental adicional atual e adicione-o a todas as suas chaves. Por exemplo:
Você tem valores como este:
Quando você precisar limpar os dados, altere o prefixo_actuall primeiro (por exemplo, defina prefix_prefix_actuall = 3), para que seu aplicativo grave novos dados nos prefixos de chaves: 3: 1 e prefixo: 3: 2. Em seguida, você pode pegar valores antigos com segurança do prefixo: 2: 1 e prefixo: 2: 2 e limpar as chaves antigas.
fonte
redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Aqui está uma versão completamente funcional e atômica de uma exclusão curinga implementada em Lua. Ele rodará muito mais rápido que a versão xargs devido a muito menos retorno e retorno da rede, e é completamente atômico, bloqueando outras solicitações contra o redis até que seja concluído. Se você deseja excluir atomicamente chaves no Redis 2.6.0 ou superior, este é definitivamente o caminho a seguir:
Esta é uma versão funcional da idéia de @ mcdizzle em sua resposta a esta pergunta. O crédito pela ideia 100% vai para ele.
EDIT: Pelo comentário de Kikito abaixo, se você tiver mais chaves para excluir do que memória livre no servidor Redis, encontrará o erro "muitos elementos para descompactar" . Nesse caso, faça:
Como Kikito sugeriu.
fonte
for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
unpack
transforma uma tabela em uma "lista de variáveis independentes" (outras línguas chamam issoexplode
), mas o número máximo não depende da memória do sistema; é fixado em lua através daLUAI_MAXSTACK
constante. No Lua 5.1 e LuaJIT é 8000 e no Lua 5.2 é 100000. A opção for loop é recomendada IMO.EVAL
pois não especifica antecipadamente as chaves nas quais irá operar. Ele deve funcionar em uma única instância, mas não espere que funcione com o Redis Cluster.Isenção de responsabilidade: a solução a seguir não fornece atomicidade.
A partir da v2.8, você realmente deseja usar o comando DIGITALIZAR em vez de KEYS [1]. O script Bash a seguir demonstra a exclusão de chaves por padrão:
[1] KEYS é um comando perigoso que pode resultar potencialmente em um DoS. A seguir, uma citação de sua página de documentação:
UPDATE: um liner para o mesmo efeito básico -
fonte
-n 1
a cadaredis-cli
invocação:redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
Para aqueles que estavam tendo problemas para analisar outras respostas:
Substitua
key:*:pattern
por seu próprio padrão e insira issoredis-cli
e você estará pronto.Crédito lisco de: http://redis.io/commands/del
fonte
Estou usando o comando abaixo no redis 3.2.8
Você pode obter mais ajuda relacionada à pesquisa de padrões de chaves aqui: - https://redis.io/commands/keys . Use o seu padrão de estilo glob conveniente como por sua exigência como
*YOUR_KEY_PREFIX*
ouYOUR_KEY_PREFIX??
ou qualquer outro.E se algum de vocês tiver integrado a biblioteca Redis PHP, a função abaixo o ajudará.
Obrigado :)
fonte
A solução do @ mcdizle não está funcionando, funciona apenas para uma entrada.
Este funciona para todas as chaves com o mesmo prefixo
Nota: Você deve substituir 'prefixo' pelo seu prefixo de chave ...
fonte
Você também pode usar este comando para excluir as chaves: -
Suponha que haja muitos tipos de chaves nos seus redis, como
Ex- ' xyz_category_fpc ' aqui xyz é um nome de site e essas chaves estão relacionadas a produtos e categorias de um site de comércio eletrônico e geradas pelo FPC.
Se você usar este comando como abaixo
OU
Exclui todas as chaves como ' xyz_category_fpc ' (exclua as teclas 1, 2 e 3). Para excluir outras teclas numéricas 4, 5 e 6, use ' xyz_product_fpc ' no comando acima.
Se você deseja excluir tudo no Redis , siga estes comandos
Com redis-cli:
Por exemplo: - no seu shell:
fonte
redis-cli del
não é atômica.Se você tiver espaço no nome das chaves, poderá usá-lo no bash:
fonte
A resposta de @ itamar é ótima, mas a análise da resposta não estava funcionando para mim, esp. no caso em que não há chaves encontradas em uma determinada varredura. Uma solução possivelmente mais simples, diretamente do console:
Isso também usa SCAN, que é preferível a KEYS na produção, mas não é atômico.
fonte
Eu apenas tive o mesmo problema. Eu armazenei os dados da sessão para um usuário no formato:
Portanto, cada entrada era um par de valores-chave separado. Quando a sessão é destruída, eu queria remover todos os dados da sessão excluindo chaves com o padrão
session:sessionid:*
- mas o redis não possui essa função.O que eu fiz: armazene os dados da sessão em um hash . Eu só criar um hash com a ID de hash
session:sessionid
e então eu empurrarkey-x
,key-y
,key-z
em que de hash (ordem não importa para mim) e se eu não preciso esse hash mais Eu só faço umDEL session:sessionid
e todos os dados associados a esse ID de hash é ido.DEL
é atômico e o acesso aos dados / gravação de dados no hash é O (1).fonte
Eu acho que o que pode ajudá-lo é o MULTI / EXEC / DISCARD . Embora não seja 100% equivalente a transações , você poderá isolar as exclusões de outras atualizações.
fonte
PARA SUA INFORMAÇÃO.
redis-cli
keys
(isso usascan
)Talvez você precise modificar apenas caracteres maiúsculos.
scan-match.sh
clear-redis-key.sh
Executar no prompt do bash
fonte
Outras respostas podem não funcionar se sua chave contiver caracteres especiais -
Guide$CLASSMETADATA][1]
por exemplo. A quebra de cada chave entre aspas garantirá que elas sejam excluídas corretamente:fonte
Uma versão que usa SCAN em vez de KEYS (como recomendado para servidores de produção) e em
--pipe
vez de xargs.Prefiro canalizar sobre xargs porque é mais eficiente e funciona quando suas chaves contêm aspas ou outros caracteres especiais que seu shell tenta e interpreta. A substituição de expressão regular neste exemplo envolve a chave entre aspas duplas e escapa as aspas duplas dentro.
fonte
Esta não é uma resposta direta à pergunta, mas como cheguei aqui ao procurar minhas próprias respostas, vou compartilhar isso aqui.
Se você tiver dezenas ou centenas de milhões de chaves com as quais corresponder, as respostas fornecidas aqui farão com que os Redis não respondam por um período significativo de tempo (minutos?) E potencialmente falhem devido ao consumo de memória (certifique-se de que o salvamento em segundo plano será chute no meio de sua operação).
A abordagem a seguir é inegavelmente feia, mas não encontrei uma melhor. A atomicidade está fora de questão aqui, neste caso, o principal objetivo é manter o Redis ativo e responsivo 100% do tempo. Funcionará perfeitamente se você tiver todas as suas chaves em um dos bancos de dados e não precisar corresponder a nenhum padrão, mas não puder usar http://redis.io/commands/FLUSHDB por causa de sua natureza bloqueadora.
A idéia é simples: escreva um script que execute em loop e use a operação O (1) como http://redis.io/commands/SCAN ou http://redis.io/commands/RANDOMKEY para obter chaves, verifique se elas corresponda ao padrão (se necessário) e http://redis.io/commands/DEL, um por um.
Se houver uma maneira melhor de fazer isso, entre em contato, atualizarei a resposta.
Exemplo de implementação com randomkey no Ruby, como uma tarefa rake, um substituto não-bloqueador de algo como
redis-cli -n 3 flushdb
:fonte
É simples implementado através da funcionalidade "Remover ramo" no FastoRedis , basta selecionar o ramo que você deseja remover.
fonte
Por favor, use este comando e tente:
fonte
Eu tentei a maioria dos métodos mencionados acima, mas eles não funcionaram para mim, depois de algumas pesquisas, encontrei estes pontos:
-n [number]
del
mas se existem milhares ou milhões de chaves, é melhor usarunlink
porque o desvincular não está bloqueando enquanto o del está bloqueando, para obter mais informações, visite esta página unlink vs delkeys
são como del e está bloqueandoentão usei esse código para excluir chaves por padrão:
fonte
apagamento atômico em massa do pobre homem?
talvez você possa configurá-los para EXPIREAT no mesmo segundo - como alguns minutos no futuro - e esperar até esse momento e vê-los todos "se autodestruir" ao mesmo tempo.
mas não tenho muita certeza de quão atômica isso seria.
fonte
Agora, você pode usar um cliente redis e executar a primeira DIGITALIZAÇÃO (suporta a correspondência de padrões) e, em seguida, DEL cada tecla individualmente.
No entanto, existe um problema no redis github oficial para criar um delineador de correspondência de patter aqui , mostre-lhe um pouco de amor se achar útil!
fonte
Eu apoio todas as respostas relacionadas a ter alguma ferramenta ou executar a expressão Lua.
Mais uma opção do meu lado:
Nos nossos bancos de dados de produção e pré-produção, existem milhares de chaves. Ocasionalmente, precisamos excluir algumas chaves (por alguma máscara), modificar por alguns critérios etc. É claro que não há como fazê-lo manualmente a partir da CLI, principalmente com sharding (512 dbs lógicos em cada físico).
Para esse propósito, escrevo a ferramenta cliente java que faz todo esse trabalho. No caso de exclusão de chaves, o utilitário pode ser muito simples, apenas uma classe:
fonte
O comando abaixo funcionou para mim.
fonte
O Spring RedisTemplate propriamente dito fornece a funcionalidade. O RedissonClient na versão mais recente descontinuou a funcionalidade "deleteByPattern".
fonte
keys
edelete
invocações.