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.