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