Persistência de dados com Redis

Conhecendo o Redis

Redis é um banco de dados para persistência de dados no modelo Key/Value escrito em C ANSI para sistemas POSIX, com uma interface de rede embutida. Isso é o que diz no site.

O que quer dizer que Redis é um "Key/Value storage engine", parecido com o memcached mas persistente. Suporta dados em String e Intergers, Lists, Sets e Ordered Sets além de Hash Tables (que suportam apenas Strings e Intergers). Usa operações atômicas (uma alteração por vez), e suporta get/set, push/pop, add/remove, union, intersect, diffs e muito mais, incluindo opções de ordenação.

Ele mantêm, por padrão, todos os dados em memória, e salva snapshots para o disco eventualmente de forma assíncrona, ou escrevendo cada mudança para um "Append Only File" (o que é mais interessante). Ele é capaz de refazer o AOF em background. Também tem suporte trivial a replicação master-slave.

O Redis é insamente rápido para escritas e leituras(muito mesmo!), tem bibliotecas para "tipo" todas as linguagens, é desenvolvido em ritmo alucinante e não funciona bem no windows.

A prioridade para próxima versão é o projeto Redis Cluster.

Instalação e Configuração do Redis

Sendo um sistema de evolução muito rápido fique de olho no código-fonte no no site oficial e nos branches do github e pegue a ultima versão. Aqui vou usar a versão 2.0 do github, seguem passos para instalação:

$ git clone git://github.com/antirez/redis.git$ cd redis$ make

Pronto o sistema está construído. Você pode agora configurar o servidor redis pelo arquivo redis.conf. Alguns detalhes interessantes da configuração:

Uma boa opção é usar o Redis com AOF (append only file), a cada escrita ele vai adicionar esse dado ao log que será a forma de persistência. Basta usar a opção "appendonly" como "yes".

Importante novidade no Redis é o uso de memoria virtual (VM), como o Redis mantém tudo em memoria isso limita a capacidade de armazenamento a memoria disponível. Usando VM o Redis pode armazenar mais dados que a memoria disponível fazendo paginação de forma inteligente.

Para ativar a VM use a opção "vm-enable" como "yes". Você pode definir o máximo de memoria para a VM usando a opção "vm-maxmemory", se esse valor for zero o sistema vai manter apenas as chaves em memoria e todo os dados em disco. Tem ainda a opção do número de threads trabalhando na paginação com "vm-max-threads", você pode usar seu numero de "cores" (+2) ou 0 para ter blocking de leitura.

Usar paginação pode ser mais lento, mas ainda assim é bem rápido e permite uma capacidade maior de armazenamento. Claro, só vai ficar mais lento se usar o sistema até ser necessário paginar.

O ideal é usar o sistema com AOF para maior consistência e durabilidade (não há impacto na performance) e usar VM com um número razoável de threads, para caso seu sistema cresça bastante você não ter nenhum susto.

Você tem ainda a opção "slaveof" para torná-lo slave de outro servidor e pode definir a opção "requirepass" para usar autenticação.

Para iniciar o servidor basta executar:

$ ./redis-server

Feitas as configurações você pode rodar os testes de sistema(demora bastante!):

$ make test

E tem também um utilitário de benchmark, bom para testar diferentes configurações:

./redis-benchmark -n 1000 -q

Usando Redis

Com o servidor iniciado (./redis-server) você pode testar o redis usando o shell interativo, basta lançá-lo usando:

$ ./redis-cli

Você pode passar para o cli as operações que quer testar, ex:

$ ./redis-cli set foo "bar"$ ./redis-cli get foo

Ou apenas usar o redis-cli para entrar em um prompt interativo.

Primeiro vamos ver um pouco dos tipos de dados do Redis.

String: O tipo mais básico, não tem mistério, são strings ou inteiros. É, inteiros também.

redis> set foo "bar"OKredis> get foo"bar"redis> set hello "Hello, "OKredis> append hello "Redis!"(integer) 13 redis> mget foo hello1."bar"2."Hello, Redis!"redis> substr hello 2 4"llo"redis> set um 1OKredis> incr um(integer) 2redis> incrby um 5(integer) 7redis> decr um(integer) 6redis> get um"6"

List: Listas no Redis não são arrays, mas Linked Lists. São mais simples e rápidas, não são associativas, aceitam Strings (que podem ser inteiros, lembra). São muito rápidas para acesso nas pontas e para adição de itens e não tão rápidas para acessos aleatórios (pelo índice).

redis> rpush nums 1redis> rpush nums 2redis> lpush nums 0redis> lrange nums 0 21."0"2."1"3."2"redis> lrange nums 0 11."0"2."1"redis> lrange nums 0 -11."0"2."1"3."2"

Explicando um pouco, "rpush" insere um item a direita na lista (final), "lpush" a esquerda (inicio) e "lrange" retorna parte da lista.

redis> rpush msgs "Oi"redis> rpush msgs "Meu nome"redis> rpush msgs "É"redis> rpush msgs "Redis!"redis>lrange msgs 0 -11."Oi"2."Meu nome"3."É"4."Redis!"redis> rpop msgs"Redis!"redis> rpop msgs"É"redis> lpop msgs"Oi"

O comando "lpop" retorna o elemento a esquerda da lista (começo) e o remove, o "rpop" o mesmo para a direita (final).

Set: É uma coleção de Strings não ordenadas.

redis> sadd users "diogok"redis> sadd users "voce"redis> sadd users "ninguem"redis> smembers users1."ninguem"2."voce"3."diogok"redis> sadd admins "ninguem"redis> sinter users admins1."ninguem"redis> sunion users admins1."ninguem"2."diogok"3."voce"redis> sdiff users admins1."diogok"2."voce"redis> sdiff admins users(empty list or set)redis> srem "ninguem"

A vantagem dos sets é permitir operações de grupos como uniões (sunion), intercessões (sinter) e diferenças (sdiff).

Sorted Set: Parecido com Sets porem ordenados.

redis> zadd log 2210 "login"redis> zadd log 2215 "view email"redis> zadd log 2225 "view twitter"redis>zrange log 0 -1redis>zrevrange log 0 -1redis> zrem log 2210

Hash: É um tipo novo (>= 2.0) que define hash tables, que contém chaves e conteúdos string.

redis> hset diogok name "Diogo"redis> hmset diogok email "manifesto at manifesto.blog.br" password "123"redis> hget diogok name"Diogo"redis> hkeys diogok1."name"2."email"3."password"redis> hvals1."Diogo"2."manifesto at manifesto.blog.br"3."123"redis> hgetall diogok1."name"2."Diogo"3."email"4."manifesto at manifesto.blog.br"5."password"6."123"redis> hset diogok counter 1redis> hincrby diogok counter 3redis> hget diogok counter4redis> hdel diogok counter

Conclusão

Isso cobre o básico do uso do Redis, agora é escolher a biblioteca para sua linguagem e consultar a documentação do Redis e a lista completa de comandos.

O Redis se mostra muito interessante por se extremamente rápido, principalmente na escrita, e seus tipos de dados como set e ordered list o torna muito prático para certas aplicaçções:

  • Os Ordered Set são ótimos para listas manterem ordem temporal (noticias, tweets, logs…)
  • Os Sets servem muito bem para traçar grafos e comparar listas (amigos em comum, aprovações…)
  • Lists são perfeitos para queues ou listas de processamentos (urls para minerar, mensagens para enviar, dados a processar…)
  • Hash Tables com Strings armazenam dados genéricos de forma mais compacta.
  • Cada um desses casos tem performance excelente!

O mais importante ao adotar o Redis(ou qualquer “nosql” na verdade) é entender a nova modelagem. Um sistema em memória não é bom entulhar com dados mal formatados, deve-se retirar periodicamente esses dados para uma armazenagem secundária. Deve-se pensar também numa estratégia consisa de chaves, ex:

redis> sadd users diogokredis> hmset users:diogok name "diogo" web "manifesto.blog.br"redis> sadd users voceredis> hmset users:voce name "voce" web "google.com"redis> sadd conhecidos:diogok voceredis> sinter conhecidos:diogok conhecidos:voce(nenhum conhecido em comum)

Você pode ver um clone do twitter com php+redis ou uma aplicação de notas com ruby+redis e ainda um motor de busca com python+redis como exemplo.

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>