Preciso expirar todas as chaves no hash redis, que têm mais de 1 mês.
107
Isso não é possível , para manter o Redis simples .
Quoth Antirez, criador do Redis:
Olá, não é possível, usar uma chave de nível superior diferente para aquele campo específico ou armazenar junto com o campo outro campo com um tempo de expiração, buscar ambos e deixar que o aplicativo entenda se ainda é válido ou não com base em hora atual.
O Redis não oferece suporte
TTL
para hashes diferentes da chave superior, que expiraria todo o hash. Se você estiver usando um cluster fragmentado, há outra abordagem que você pode usar. Essa abordagem pode não ser útil em todos os cenários e as características de desempenho podem ser diferentes das esperadas. Ainda vale a pena mencionar:Ao ter um hash, a estrutura basicamente se parece com:
Visto que queremos adicionar
TTL
as chaves filhas, podemos movê-las para as chaves superiores. O ponto principal é que a chave agora deve ser uma combinação de umahash_top_key
chave filha:Estamos usando a
{}
notação de propósito. Isso permite que todas as chaves caiam na mesmahash slot
. Você pode ler mais sobre isso aqui: https://redis.io/topics/cluster-tutorialAgora, se quisermos fazer a mesma operação de hashes, poderíamos fazer:
O interessante aqui é
HGETALL
. Primeiro, obtemos ashash slot
chaves para todos os nossos filhos. Em seguida, obtemos as chaves para aquele particularhash slot
e, finalmente, recuperamos os valores. Precisamos ter cuidado aqui, pois pode haver mais do quen
chaves para issohash slot
e também pode haver chaves nas quais não estamos interessados, mas que têm as mesmashash slot
. Na verdade, poderíamos escrever umLua
script para fazer essas etapas no servidor executando um comandoEVAL
ouEVALSHA
. Novamente, você precisa levar em consideração o desempenho dessa abordagem para seu cenário específico.Mais algumas referências:
fonte
Existe um framework Java Redisson que implementa
Map
objeto hash com suporte TTL de entrada. Ele usahmap
ezset
objetos Redis sob o capô. Exemplo de uso:Essa abordagem é bastante útil.
fonte
Isso é possível no KeyDB, que é um fork do Redis. Por ser um Fork, é totalmente compatível com o Redis e funciona como um substituto.
Basta usar o comando EXPIREMEMBER. Funciona com conjuntos, hashes e conjuntos classificados.
Você também pode usar TTL e PTTL para ver a validade
Mais documentação está disponível aqui: https://docs.keydb.dev/docs/commands/#expiremember
fonte
Em relação a uma implementação de NodeJS, adicionei um
expiryTime
campo personalizado no objeto que salvo no HASH. Então, após um período específico, eu limpo as entradas HASH expiradas usando o seguinte código:fonte
Array.filter
para criar uma matriz dekeys
para excluir do hash e, em seguida, passar paraclient.hdel(HASH_NAME, ...keys)
em uma única chamada.const keys = Object.keys(reply).filter(key => reply[key] && JSON.parse(reply[key]).expiryTime < Date.now()); client.hdel(HASH_NAME, ...keys);
Você pode. Aqui está um exemplo.
Use EXPIRE ou EXPIREAT comando.
Se você deseja expirar chaves específicas no hash com mais de 1 mês. Isso não é possível. O comando de expiração do Redis é para todas as chaves no hash. Se você definir a chave hash diária, poderá definir uma hora de vida das chaves.
fonte
Você poderia armazenar chaves / valores no Redis de maneira diferente para conseguir isso, apenas adicionando um prefixo ou namespace às suas chaves ao armazená-las, por exemplo, "hset_"
Obtenha uma chave / valor
GET hset_key
igual aHGET hset key
Adicionar uma chave / valor
SET hset_key value
igual aHSET hset key
Pegue todas as chaves
KEYS hset_*
iguais aHGETALL hset
Obter todos os vals deve ser feito em 2 operações, primeiro pegue todas as chaves e, em
KEYS hset_*
seguida, obtenha o valor de cada chaveAdicione uma chave / valor com TTL ou expire, o que é o tópico da questão:
Nota :
KEYS
irá pesquisar a correspondência da chave em todo o banco de dados, o que pode afetar o desempenho, especialmente se você tiver um banco de dados grande.Nota:
KEYS
irá pesquisar a correspondência da chave em todo o banco de dados, o que pode afetar o desempenho, especialmente se você tiver um banco de dados grande. enquantoSCAN 0 MATCH hset_*
pode ser melhor, desde que não bloqueie o servidor, mas ainda assim o desempenho é um problema no caso de banco de dados grande.Você pode criar um novo banco de dados para armazenar separadamente essas chaves que deseja expirar, especialmente se forem um pequeno conjunto de chaves.
fonte
hashset
.. get O (1) set O (1) get all O (n)O(n)
para número de coisas no conjunto,KEYS
para número de coisas no banco de dados.scan 0 match namespace:*
pode ser melhor, desde que não bloqueie o servidorTivemos o mesmo problema discutido aqui.
Temos um hash Redis, uma chave para entradas de hash (pares nome / valor) e precisamos manter os tempos de expiração individuais em cada entrada de hash.
Implementamos isso adicionando n bytes de dados de prefixo contendo informações de expiração codificadas quando gravamos os valores de entrada de hash, também definimos a chave para expirar no momento contido no valor sendo escrito.
Então, na leitura, decodificamos o prefixo e verificamos a validade. Esta é uma sobrecarga adicional, entretanto, as leituras ainda são O (n) e a chave inteira expirará quando a última entrada hash expirar.
fonte
Você pode usar as notificações do Redis Keyspace usando
psubscribe
e"__keyevent@<DB-INDEX>__:expired"
.Com isso, cada vez que uma chave expirar, você receberá uma mensagem publicada em sua conexão do redis.
Em relação à sua pergunta basicamente você cria uma chave "normal" temporária
set
com um tempo de expiração em s / ms. Deve corresponder ao nome da chave que você deseja excluir do seu conjunto.Como sua chave temporária será publicada na conexão do redis com o
"__keyevent@0__:expired"
quando expirar, você pode excluir facilmente sua chave do conjunto original, pois a mensagem terá o nome da chave.Um exemplo simples na prática nessa página: https://medium.com/@micah1powell/using-redis-keyspace-notifications-for-a-reminder-service-with-node-c05047befec3
doc: https://redis.io/topics/notifications (procure o sinalizador xE)
fonte
Você pode usar Sorted Set no redis para obter um contêiner TTL com carimbo de data / hora como pontuação. Por exemplo, sempre que você inserir uma string de evento no conjunto, poderá definir sua pontuação para a hora do evento. Assim, você pode obter dados de qualquer janela de tempo chamando
zrangebyscore "your set name" min-time max-time
Além disso, podemos expirar usando
zremrangebyscore "your set name" min-time max-time
para remover eventos antigos.A única desvantagem aqui é que você precisa fazer a manutenção de um processo externo para manter o tamanho do conjunto.
fonte
Você pode expirar hashes Redis facilmente, por exemplo, usando python
Isso irá expirar todas as chaves filhas em hash hashed_user após 10 segundos
o mesmo de redis-cli,
após 10 segundos
fonte
hset
filho não o completohset
.