Conceitos do Redis: Chaves

Desmistificando o conceito de chaves do Redis

Rodrigo Martins
4 min readSep 15, 2023
Photo by Samantha Lam on Unsplash

Recentemente iniciei uma série de estudos sobre Redis com foco em realizar a prova para obter sua certificação, a ideia é gerar uma série de artigos como material de estudo para ajudar nessa tarefa.

No Redis, chaves são a forma primária de acessar valores. A maioria dos comandos no Redis operam uma ou várias chaves, portanto parece natural que deva ser um dos conceitos iniciais a serem entendidos.

Possuindo um tamanho máximo de 512MB, os nomes de chaves são únicos e binários seguros, ou seja, uma sequência de binário também pode ser utilizada como chave.

Apesar dos nomes de chaves possuírem um tamanho máximo no mínimo generoso, não é muito recomendada a utilização de chaves muito longas, já que elas também ocupam espaço na memória.

Como o nome da chave é uma sequencia de binários, por implicação, ele também é case sensitive, portanto no exemplo abaixo, cada nome representa uma chave diferente.

- registeredusers:1000:followers
- RegisteredUsers:1000:followers
- registeredUsers:1000:followers

O servidor realiza uma comparação binária na chave para determinar se ela já existe antes de ser recuperada ou modificada.

Segregação das chaves

O Redis possui uma separação em bancos de dados lógicos e, dentro de cada banco, todas as chaves ocupam o mesmo espaço. Não existe separação automática dos nomes das chaves em grupos nomeados como buckets ou collections, portanto, não há a necessidade de realizar o gerenciamento de namespaces.

Na prática significa que o desenvolvedor deve investir um tempinho pensando em seus namespaces de acordo com seus usos desejados.

Normalmente os usuários do Redis utilizam um nome de chave estruturado, geralmente utilizando “:” como separador. Como por exemplo, uma chave para armazenar seguidores de um usuário pode ser montada da seguinte forma: user:${id}:followers.

Na prática este formato é apenas uma convenção utilizada pela comunidade do Redis, mas você é livre para utilizar o formato que julgar ser melhor. Independente da escolha, é importante que a haja uma consistência na utilização do formato entre o time e o projeto. Isso se torna crítico quando múltiplos times, projetos ou microserviços vão utilizar a mesma instância do Redis.

Bancos de dados lógicos

Os banco de dados lógicos são identificados por um índice iniciado em zero, sendo zero o índice do banco padrão.

Dentro de um banco lógico, os nomes de chaves são únicos, contudo, uma chave pode existir em múltiplos bancos lógicos, visto que os bancos lógicos realizam a separação dos nomes das chaves.

Algumas restrições de utilizar o banco de dados lógicos são que o cluster do Redis suporta apenas o banco 0 e o suporte para bancos de dados lógicos não é ubiquo entre ferramentas e frameworks. Muitas ferramentas e frameworks assumem que o banco utilizado é o 0.

Listando chaves existentes

Existem dois comandos para listar os nomes de chaves existentes no redis, o primeiro é chamado KEYS e o segundo é chamado SCAN. É possível utilizar esses comandos para iterar sobre todas as chaves do banco de dados do Redis ou listar todas as chaves que possuem um determinado padrão.

Comando KEYS

O comando KEYS deve ser utilizado com muita cautela, pois ele lista todas as chaves de acordo com o padrão informado sem paginação, logo para bases de dados muito grandes, ele poderá acarretar em problemas de performance.

Exemplo de uso:

#Lista chaves que contém a string "name"
redis> KEYS *name*
1) "lastname"
2) "firstname"
#Lista TODAS as chaves existentes na base de dados
redis> KEYS *
1) "age"
2) "lastname"
3) "firstname"

Comando SCAN

O comando SCAN porporciona uma forma eficiente de iterar sobre as chaves existentes em sua base de dados. O comando pode ser utilizado em produção sem os problemas que o comando KEYS apresenta, já que ele permite uma iteração incremental, retornando apenas uma pequena quantidade de dados por chamada.

O comando implementa uma paginação por cursor, então a cada chamada é retornado um cursor atualizado que o usuário deve utilizar como argumento na próxima chamada. A iteração começa com o cursor 0 e termina quando o servidor retornar novamente o cursor 0, indicando o retorno ao início dos registros.

Exemplo de uso:

redis> scan 0
1) "17" #Próximo cursor retornado
2) 1) "key:12"
2) "key:8"
3) "key:4"
4) "key:14"
5) "key:16"
6) "key:17"
7) "key:15"
8) "key:10"
9) "key:3"
10) "key:7"
11) "key:1"
redis> scan 17
1) "0" #Como não existem novos dados, é retornado o valor 0
2) 1) "key:5"
2) "key:18"
3) "key:0"
4) "key:2"
5) "key:19"
6) "key:13"
7) "key:6"
8) "key:9"
9) "key:11"

Expiração de chaves

O tempo para a expiração de chaves (TTL) é o tempo em que a chave deve ser mantida na base de dados, ou seja, após aquele período, a chave é removida da base automáticamente. O TTL pode ser definido em milisegundos, segundos ou em UNIX timestamp.

O TTL pode ser definido para chaves existentes ou no momento da criação da chave. Para chaves com TTL já definido, ele pode ser removido e ela não expirará mais.

Para saber o TTL de uma chave basta utilizar o comando TTL (em segundos) ou PTTL (em milisegundos).

redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10 # Definindo tempo de expiração em 10 segundos
(integer) 1
redis> TTL mykey
(integer) 9 # Tempo até a chave ser expirada em segundos
redis> PTTL mykey
(integer) 8000 # Tempo até a chave ser expirada em milisegundos
redis> PERIST mykey # Removendo o tempo de expiração da cahve
(integer) 1
redis> TTL mykey
(integer) -1 # Valor retornado quando a chave não possui tempo de expiração

Referências

--

--

Rodrigo Martins

Falo sobre técnicas de desenvolvimento, melhorias de performance e experiências de usuário em websites.