- Published on
Redis in five minutes for portuguese speakers
Redis em 5 minutos
Conteúdo em português com o objetivo de mitigar o uso do Redis de forma simples, objetiva e quase
completa.
Índice de navegação:
O que é o Redis?
Cache? Banco de Dados? Mediador de Mensagens?
O redis é um armazenador
em memória de estrutura de dados
, que utiliza o mecanismo do tipo chave/valor
(key/value
) para acesso á dados. Isto significa que para armazenar qualquer valor
, uma chave de acesso
é atribuída á aquele valor. Para se acessar um valor
é necessário conhecer sua chave
.
O termo: estrutura de dados
refere-se ao fato dos valores
das chaves
armazenadas poderem conter estrutura de dados complexas
.
Comumente, Redis é utilizado para implementar cache
enquanto o banco de dados principal é um RDBMS ou um NoSQL (baseado em disco).
O que faz o Redis ser diferente de outras implementações de cache é sua velocidade e capacidade de persistir dados no disco.
Além disso, Redis pode ser usado como banco de dados
e Corretor/Mediador de Mensagens
.
Cenários onde o Redis armazena dados que não são armazenados em nenhum outro lugar, fazem do Redis um banco de dados.
Como Mediador de Mensagens
, o Redis implementa o padrão Publicar/Assinar
(Publish/Subscribe
) paralelamente á estrutura de dados (particularmente as Listas)
Tipos de estruturas de dados
que o Redis oferece:
String
Sequência de caracteres. É a estrutura de dados mais simples
do Redis.
Operações atômicas.
Hash
Conhecido como Mapa, Dicionário ou vetor associativo.
Acesso e manipulação rápida de dados.
Basicamente é uma coleção de campo/valor
É a estrutura de dados mais flexível do Redis. O redis funciona exatamente como um hash.
Exemplo de Uso: Session, Perfil de Usuário, Documentos JSON
List
Lista Ordenada de Strings com índices numérico.
Tempo: O(1) para adicionar ou remover itens mesmo com milhões de items
Exemplo de Uso: Filas. Facilita a implementação do padrão assíncrono
produtor-consumidor
.
Set (Conjunto)
Conjunto desordenado de Strings únicas. Oferece comandos para Diferença
, Interseção
e União
São mais perfomáticos do que hash
para solucionar problemas de filiação
, por exemplo: Esse item está presente nesse conjunto de dados?
Exemplo de Uso: Interesses
de um consumidor, Conjunto de Amigos
de um usuário.
Sorted Set with range queries
Conjunto ordenado por classificação
de Strings únicas. Ao armazenar um valor, é associado a sua pontuaçào que é um valor.
Alta performance
em ordenamento
Bom para buscar dados ordenados via classificação numérica e de forma simples.
Exemplo de Uso: Coleção de dados do tipo série temporal
, lances de um leilão, compras X valor de compra, itens mais visualizados, quadro de classificação de um game.
Geospatial index
É uma forma especial
da implementação de Conjunto Ordenado
, onde a classificação númerica do item é uma coordenada geográfica.
Muito rápido para implementação de buscas dentro de uma área específica.
Bitfield - Bitmap
Vetores
de Bit
são usados para contar
informações, mas limitando o consumo de memória.
Ideal para casos onde é necessário lidar com grande volume de dados e consumir memória de forma eficiente.
HyperLogLog
É uma estrutura de dados usada para estimar/contar itens únicos. Foco em eficiência de memória e processamento.
Stream
Fluxo de dados
Implementa uma estrutura de dados do tipo fluxo de log. Primariamente funciona no modo acrescentar informações no final
somente.
É a estrutura de dados mais complex do Redis
Permite um grupo de clientes cooperar entre si, consumindo uma porção diferente do mesmo stream de mensagems.
Não é muito diferente de uma Lista
, exceto pelo fato de possuir uma API blocking
mais completa.
É composto por um
ou mais pares
de campo-valor
Os fluxos de dados do Redis oferecem suporte a consultas de intervalo por ID.
Comandos
Iniciar Redis informando um arquivo de configuração
redis-server /path/redis.conf
Iniciar o prompt do Redis
redis-cli
Manipulando Strings.
# cria uma chave com um valor associado
> SET chave valor
# Tempo: O(1)
# cria uma chave com um valor associado SE a chave não existir
> SETNX chave valor
# Tempo: O(1)
# recupera o valor de uma chave
> GET chave
# Tempo: O(1)
# associa um novo valor á chave especificada e retorna o valor antigo da chave
> GETSET chave valor
# Tempo: O(1)
# Adiciona um valor ao final do valor de uma chave
> APPEND chave value
# Tempo:
# recupera o comprimento de um valor associado á chave dada.
> STRLEN chave
# Tempo:
# cria múltiplas chaves com um valor associado
> MSET chave1 valor1 chave2 valor2
# Tempo: O(1) para setar cada chave
# cria múltiplas chaves com um valor associado, somente se nenhuma das chaves existirem
> MSETNX chave1 valor1 chave2 valor2
# Tempo: O(1) para setar cada chave
# recupera o valor de múltiplas chaves
> MGET chave1 chave2
# Tempo: O(1) para cada chave
# substituir parte da string armazenada na chave na posição especificada
# SET chave "Hello World"
> SETRANGE chave 6 "Redis"
# "Hello Redis"
# Tempo: O(1)
# recupera uma substring do valor armazenado na chave, determinada pelas posições
# inicio e fim (ambos inclusivos).
# -1 no fim significa até o último char
# -2 no fim significa até o penúltimo char
> GETRANGE chave inicio fim
# Ex:
# SET chave "Isto é uma substring"
# GETRANGE chave 0 3
# "Isto"
# Tempo: O(n)
# Conta o número de conjunto de bits em uma string.
> BITCOUNT key [start end]
# Tempo: O(n)
Manipulando Contadores.
# incrementa em mais 1 o valor de uma chave to tipo contador
> INCR chave
# Tempo: O(1)
# incrementa em mais X o valor de uma chave to tipo contador, onde X é um número inteiro
> INCRBY chave numero
# Tempo: O(1)
# incrementa em mais X o valor de uma chave to tipo contador, onde X é um número float
> INCRBYFLOAT chave numero
# Tempo:
# Decrementa em menos 1 o valor de uma chave to tipo contador
> DECR chave
# Tempo: O(1)
# incrementa em menos X o valor de uma chave to tipo contador, onde X é um número
> DECRBY chave numero
# Tempo: O(1)
Manipulando Lists.
Listas
Conceito básico, listas se comportam como uma fila, onde o primeiro que entra, é o primeiro que sai (FIFO - First in, First out
). Diferente de um vetor padrão, a contagem começa da direta pra esquerda.
# adiciona um ou mais itens no `começo` da lista fila_atendimento
> RPUSH fila_atendimento 'Jose Eduardo' 'Maria da Silva' 'Renato Casagrande' 'Daylla Reis'
# Os itens são indexados na mesma ordem dos valores dados.
# 'Jose Eduardo' 'Maria da Silva' 'Renato Casagrande' 'Daylla Reis'
# Tempo: O(1) para cada elemento
# adiciona um ou mais itens no `começo` da lista, SOMENTE SE a chave já existir E
# armazenar uma lista
> RPUSHX fila_atendimento 'Pedro Cabral'
# 'Jose Eduardo' 'Maria da Silva' 'Renato Casagrande' 'Daylla Reis' 'Pedro Cabral'
# Tempo: O(1) para cada elemento
# adiciona um ou mais itens na `final` da lista
> LPUSH fila_atendimento 'Joe Biden'
# 'Joe Biden' 'Jose Eduardo' 'Maria da Silva' 'Renato Casagrande' 'Daylla Reis' 'Pedro Cabral'
# Os itens são indexados inversamente ordenado
# Exemplo:
> LPUSH fila_atendimento2 'Jose Eduardo' 'Maria da Silva'
> LRANGE fila_atendimento2 0 1 # 'Maria da Silva' 'Jose Eduardo'
# Tempo: O(1) para cada elemento
# recupera sublista compreendida entre o dada a posição do index inicial e final.
# Caso forneça -1 como último valor, a busca compreenderá até o último item da lista
# Caso forneça -2 como último valor, a busca compreenderá até o penúltimo item
# da lista e assim sucessivamente
> LRANGE fila_atendimento 0 -1
# "Joe Biden" "Jose Eduardo" "Maria da Silva" "Renato Casagrande" "Daylla Reis" "Pedro Cabral"
# Tempo: O(n)
# recupera um elemento de uma lista dado a posição de seu index
> LINDEX fila_atendimento 1
# "Jose Eduardo"
# Tempo: O(n)
# adiciona um elemento antes ou depois de um elemento da lista
> LINSERT fila_atendimento BEFORE 'Jose Eduardo' 'Joana Dark'
# "Joe Biden" "Joana Dark" "Jose Eduardo" "Maria da Silva" "Renato Casagrande"
# "Daylla Reis" "Pedro Cabral"
> LINSERT fila_atendimento AFTER 'Jose Eduardo' 'Maria Padilha'
# "Joe Biden" "Joana Dark" "Jose Eduardo" "Maria Padilha" "Maria da Silva"
# "Renato Casagrande" "Daylla Reis" "Pedro Cabral"
# Tempo:
# O(1) {se adicionar na saida da lista}
# O(n) {se adicionar na entrada da lista}
# recupera o tamanho da fila
> LLEN fila_atendimento
# Tempo: O(1)
# seta o valor de um item da lista dado o seu index e valor
> LSET fila_atendimento 2 'Jose Eduardo Almeida'
# "Joe Biden" "Joana Dark" "Jose Eduardo Almeida" "Maria Padilha" "Maria da Silva"
# "Renato Casagrande" "Daylla Reis" "Pedro Cabral"
# Tempo: O(n) e O(1) se for no inicio ou final da lista
# corta uma lista de forma que ele compreenda somente os itens dado o alcance especificado
> LTRIM fila_atendimento 1 4
# "Maria Padilha" "Maria da Silva" "Renato Casagrande" "Daylla Reis"
# Tempo: O(n)
# atomicamente remove o PRIMEIRO elemento da lista e retorna ele (ÚLTIMO da fila)
> LPOP fila_atendimento
# Tempo: O(1)
# remove o ÚLTIMO elemento da lista e retorna ele (PRIMEIRO da fila)
> RPOP fila_atendimento
# Tempo: O(n)
# atomicamente remove o ultimo elemento em uma lista (PRIMEIRO da fila), e adiciona no
# inicio de uma outra lista (ÚLTIMO da fila)
> RPOPLPUSH fila_atendimento fila_atendimento_prioritario
# Tempo: O(1)
# versào blocking do LPOP. Remove e retorna o primeiro elemento da
# lista (ultimo da fila).
# Se o comando não encontrar nenhum item disponível em nenhuma das listas,
# ele bloqueará até alguém executar um LPUSH ou RPUSH em alguma das chaves
# 0 é o timeout
> BLPOP fila_atendimento fila_atendimento_prioritario 0
# Tempo: O(1)
# versào blocking do RPOP. Remove e retorna o último elemento de multiplas
# listas (primeiro da fila).
# Se o comando não encontrar nenhum item disponível em nenhuma das listas,
# ele bloqueará até alguém executar um LPUSH ou RPUSH em alguma das chaves
# 0 é o timeout
> BRPOP fila_atendimento fila_atendimento_prioritario 0
# Tempo: O(1)
Manipulando Sets.
Conjuntos
Conceito básico: como em um conjunto numérico, items não se repetem nunca.
# Adiciona um ou mais membros em um conjunto
> SADD amigos_do_joao 'Jose' 'Pedro' 'Daylla' 'James'
> SADD amigos_da_maria 'Lily' 'Luiza' 'Daylla' 'Iza'
# Tempo: O(1) para cada item
# recupera o número de membros em um conjunto
> SCARD amigos_do_joao
# 3
# Tempo: O(1)
# Remove itens do conjunto
> SREM amigos_do_joao 'Pedro'
# 'Jose' 'Daylla' 'James'
# Tempo: O(n)
# Checa se o valor dado é membro do conjunto
> SISMEMBER amigos_do_joao 'Daylla'
# 1
# Tempo: O(1)
# retorna uma lista de todos os membros do conjunto
> SMEMBERS amigos_do_joao
# Tempo: O(N) onde N é a cardinalidade do conjunto
# Faz a união de dois ou mais conjuntos
> SUNION amigos_do_joao amigos_da_maria
# 'Jose' 'Pedro' 'Daylla' 'James' 'Lily' 'Luiza' 'Iza'
# Tempo: O(N)
# Faz a interseção de dois ou mais conjuntos
> SINTER amigos_do_joao amigos_da_maria
# 'Daylla'
# Tempo: O(N*M) no pior cenário, onde N é a cardinalidade do menor grupo
# e M é o número de conjuntos
# Move um item de um conjunto para outro conjunto
> SMOVE amigos_do_joao amigos_da_maria 'Jose'
# Tempo: O(1)
# remove um ou multiplos items do conjunto de forma randômica
> SPOP amigos_do_joao 2
# Tempo: O(1)
Manipulando Sorted Sets
Conjuntos ordenados
# adiciona um ou mais itens ao conjunto ordenado, caso já exista, atualiza o score
> ZADD hackers 1940 "Alan Kay" 1906 "Grace Hopper" 1953 "Richard Stallman" 1965 "Yukihiro Matsumoto" 1916 "Claude Shannon"
# Tempo: O(log(N)) para cada item adicionado
# recupera o número de itens em um grupo ordenado
> ZCARD hackers
# 5
# Tempo: O(1)
# conta os membros de um grupo ordenado dentro do intervalo de scores especificado
> ZCOUNT hackers 1906 1930
#2
# Tempo: O(log(N))
# incrementa o score de um membro em um grupo ordenado
> ZINCRBY hackers 1 "Alan Kay"
# 1941 "Alan Kay" 1906 "Grace Hopper" 1953 "Richard Stallman"
# 1965 "Yukihiro Matsumoto" 1916 "Claude Shannon"
# Tempo: O(log(N))
# recupera um sub conjunto de um conjunto ordenado dado posição inicial e final
# A ordem dos elementos se dá do menor para o maior score
# > ZRANGE hackers start stop [WITHSCORES]
> ZRANGE hackers 2 5
# "Claude Shannon" "Alan Kay" "Richard Stallman" "Yukihiro Matsumoto"
> ZRANGE hackers 2 5 WITHSCORES
# 1940 "Alan Kay" 1953 "Richard Stallman" 1965 "Yukihiro Matsumoto" 1916 "Claude Shannon"
# Tempo: O(log(N)+M)
# recupera o index de um membro em um conjunto ordenado
> ZRANK hackers "Alan Kay"
# 2
# Tempo: O(log(N))
# Remove um ou mais itens de um conjunto ordenado
> ZREM hackers "Alan Kay"
# 1906 "Grace Hopper" 1953 "Richard Stallman" 1965 "Yukihiro Matsumoto"
# 1916 "Claude Shannon"
# Tempo: O(M*log(N))
# onde N é número de elementos presente no conjunto
# onde M é o número de elementos a serem removidos
# Remove todos os membros de um conjunto ordenado dentro dos indexes especificados
> ZREMRANGEBYRANK hackers 1 3
# "Grace Hopper" "Richard Stallman" "Yukihiro Matsumoto"
# Tempo: O(log(N)+M)
# onde N é número de elementos presente no conjunto
# onde M é o número de elementos removidos na operação
# Remove todos os membros de um conjunto ordenado, com scores compreendidos
# entre mínimo e máximo (inclusivo)
> ZREMRANGEBYSCORE hackers min max
# Tempo: O(log(N)+M)
# onde N é número de elementos presente no conjunto
# onde M é o número de elementos removidos na operação
# recupera o score associado á um membro do conjunto ordenado
> ZSCORE hackers "Grace Hopper"
# 1906
# Tempo: O(1)
# retorna um subconjunto do conjunto ordenado baseado no score
# ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
> ZRANGEBYSCORE hackers 0 2000
# "Grace Hopper" "Claude Shannon" "Alan Kay" "Richard Stallman" "Yukihiro Matsumoto"
# Tempo: O(log(N)+M)
# onde N é número de elementos presente no conjunto
# onde M é o número de elementos removidos na operação
Manipulando Hashes
Mapas / Dicionários
# Seta o valor de uma chave em um hash
> HSET perfil_do_eduardo nome 'José Eduardo Almeida'
# Tempo: O(1)
# Recupera o valor do campo de uma chave especificada de um hash
> HGET perfil_do_eduardo nome
# 'José Eduardo Almeida'
# Tempo: O(1)
# Recupera todos campos e chaves de um hash
> HGETALL perfil_do_eduardo
# "nome" "José Eduardo"
# Tempo: O(N)
# set o valor de um capo do hash, somente se o campo não existir
> HSETNX perfil_do_eduardo nome 'James'
# HGETALL perfil_do_eduardo
# "nome" "José Eduardo"
# Tempo: O(1)
# set o valor de multiplos campos de um hash
> HMSET perfil_do_eduardo idade '36' filha 'Daylla'
# Tempo: O(N)
# incrementa o valor de um campo de um hash dado um numero como parametro
> HINCRBY perfil_do_eduardo idade 1
# 37
# Tempo: O(1)
# Remove um ou mais itens de um hash
> HDEL chave campo1 campo2
# Tempo: O(N)
# checa a existencia de um campo em um hash
> HEXISTS perfil_do_eduardo nome
# 1
# Tempo: O(1)
# recupera uma lista com o nome de todos os campos de um hash
> HKEYS perfil_do_eduardo
# nome idade filha
# Tempo: O(N)
# recupera o numero de campos dentro do hash
> HLEN perfil_do_eduardo
# Tempo: O(1)
# recupera o tamanho da string armazenada como valor do campo de um hash
> HSTRLEN perfil_do_eduardo nome
# Tempo: O(1)
# recupera uma lista com os valores associado a todos os campos de um hash
> HVALS perfil_do_eduardo
# Tempo: O(N)
Manipulando HyperLogLog
# Adiciona os itens especificados á um hyperloglog
> PFADD chave elemento1 elemento2
# Tempo: O(1) para cada elemento
# recupera a cardinalidade aproximada de um conjunto
# observado pelo hyperloglog na chave especifica
> PFCOUNT chave1 chave2
# Tempo: O(1) para uma chave e O(n) para multiplas chaves
# Combina multiples valores de hyperlolog em um valor unique que será aproximado
# á cardinalidade da união dos conjuntos observados
> PFMERGE conjunto_destino conjunto_base1 conjunto_base2
# Tempo: O(N)
Manipulando Publicação / Assinatura
# Escuta por todas as mensagens enviadas em canais que correspondam aos padrões fornecidos
> PSUBSCRIBE padrao1 padrao2
# Tempo: O(N)
# comando de introspecção que permite inspecionar o estado do subsistema Pub / Sub.
# É composto de subcomandos documentados separadamente
> PUBSUB subcomando argumento1 argumento2
# Tempo: O(N)
# Envia uma mensagem para o canal especificado
> PUBLISH canal mensagem
# Tempo: O(N+M)
# onde N é o número de clientes assinantes e M é o total de padroes assinantes
# Para de Escutar as mensagens enviadas em canais que correspondam aos padrões fornecidos
> PUNSUBSCRIBE padrao1 padrao2
# Tempo: O(N+M)
# onde N é o número de clientes assinantes e M é o total de padroes assinantes
# Escutar por mensagens em um canal especificado
> SUBSCRIBE canal1 canal2
# Tempo: O(N)
# Escutar por mensagens em um canal especificado
> UNSUBSCRIBE canal1 canal2
# Tempo: O(N)
Manipulando Streams
# * auto generated id
> XADD meustream * sensor-id 1234 temperatura 19.8
# returns stream ID 1518951480106-0
> XLEN meustream
# (integer) 1
Outros comandos
# RECUPERA todas as chaves dado o padrão glob fornecido.
KEYS glob
keys <padrão # use com cuidado em produção
keys prefixo*
keys *padrão*
keys *sufixo
keys [a-c]* # expressoes tipo grep
# Exemplos:
# h?llo retornará hello hallo hhllo
# h*llo retornará hllo heeeello
# h[ae]llo retornará hello e hallo, mas não hillo
# Tempo: O(n)
# deleta todas as chaves dadas
> DEL chave1 chave2
# Tempo: O(1)
# Configura uma chave pra expirar em X segundos, onde X é um número
> EXPIRE chave segundos
# Tempo: O(1)
# Recupera o tempo de vida de uma chave
> TTL chave
# Tempo: O(1)
# Checa a existência de uma chave dada
> EXISTS chave
# Tempo: O(1)
# Assiste os comandos ao vivo. Seja cuidadoso ao usar em produção.
> MONITOR
# recupera informações sobre o Redis
> INFO
# Faz o dum de um banco em background
> BGSAVE
# Lista clientes conectados
> CLIENT LIST
# Tempo: O(N)
# Termina a conexao de um cliente
> CLIENT KILL <IP>:<porta>
# Tempo: O(N)
# Recupera os ultimos 25 ultimos comandos mais lentos
> SLOWLOG RESET
# espera por um tempo
SLOWLOG GET 25