[SP-pm] Riak::Light
Tiago Peczenyj
tiago.peczenyj at gmail.com
Tue May 14 08:00:40 PDT 2013
Ola Povo
Agora que foi oficialmente lançado eu posso comentar com calma
https://github.com/Weborama/Riak-Light
Em Abril eu comecei a trabalhar na Weborama, uma empresa francesa que
emprega alguns caras da comunidade como o OvidPerl e o Sukria. Estou na
area de Big Data e fazemos uso intenso de Redis e Riak. Apesar de termos
varias opções no CPAN, sofremos em termos de performance com o Net::Riak -
que é o unico que suporta a API PBC, que é um protocolo binario simples em
cima de Protocol Buffers e bem mais "rapido" que a interface REST.
Resolvemos criar um cliente bem enxuto, com foco em velocidade e que não
implementa todas as features de um projeto como Data::Riak. Para quem não
conhece o Riak é um banco de dados "chave / valor" que tem varias features
interessantes (ver http://docs.basho.com/riak/1.3.1/ ).
Definido que o que era necessario era basicamente um CRUD (get, put, del),
comecei a fazer o projeto usando Moo (subset to Moose mas com foco em
performance) e o projeto ficou relativamente rapido (basta ver os
benchmarks).
Porém exista uma feature importante para ser suportada nesse novo cliente:
Timeout de IO. Era interessante setar um tempo maximo para cada operação
(leitura ou escrita). E ai, comofas/
Resolvi ser pragmatico e procurar algum modulo pronto. Não tem. No maximo
eu poderia usar AnyEvent. Inconformado fui ao google e encontrei pelo menos
3 formas
1 Usar Alarm
2 Usar select
3 Usar setsockopt e setar timeout de entrada e saida
Alarm eu poderia fazer de duas formas: uma é setar na mão o alarm em cada
operação e a outra é usar o modulo Time::Out, assim eu controlo que cada
operação não vai demorar mais q x tempos. Win32 nem pensar.
Select é mais "elegante". Aqui o conceito é modificado levemente e eu
aguardo por x tempo até poder escrever ou ler. Ainda posso bloquear e levar
mais tempo porém parece suprir as necessidades. Como em alguns testes
usando um sleep dentro do servidor eu ainda conseguia escrever, eu testei a
alternativa de usar select apenas para ler. Deve funcionar no Win32.
O setsockopt é o mais bizarro. Eu preciso enfiar um C struct timeval com
segundo, microssegundo nas propriedades do socket. Funciona como magia
negra. A parte ruim é a portabilidade disso sem ter q apelar pra XS
(pack/unpack e ainda estou devendo suporte ao NetBSD), a parte boa é que
tem quase nada de overhead.
Resultado: criei um sistema plugavel para trocar de estratégia de timeout e
fazer os testes, assim basta fazer
my $client->new( host => 'foo', port => 9999, timeout_provider =>
'Riak::Light::Timeout::Select', timeout => 0.5);
e pronto. O padrão é não suportar IO Timeout. Por enquanto vcs podem
escolher entre 5 estratégias:
Riak::Light::Timeout::Alarm
Riak::Light::Timeout::Select
Riak::Light::Timeout::SelectOnRead
Riak::Light::Timeout::SetSockOpt
Riak::Light::Timeout::TimeOut
Dessa forma eu consegui fazer um benchmark e saber qual tinha mais overhead
e qual poderia não funcionar direito.
O codigo fonte esta ai e vcs podem criticar a vontade. Este é o primeiro
projeto open source da Weborama e esta disponivel no CPAN.
Pra vcs terem uma ideia: Timeout de IO é tão bizarro q eu tenho q abandonar
a conexão pq não sei quanto "foi" ou "veio", a conexão fica num estado q
não é seguro usar sob pena de ler dados corrompidos.
O Stan me deu varias dicas sobre essa parte e eu agradeço. De cara eu penso
em remover essa parte de socket com timeout para outro projeto no futuro.
Analisei varios projetos como Redis, RedisDB e outros para ver como eles
faziam e é uma sacola de gatos essa parada.
Só depois eu encontrei este módulo:
https://metacpan.org/module/CHRMUE/Socket-Class-2.258/Class.pod
que podia me ajudar parcialmente. Eu tenho uma issue com alguns sistemas
operacionais como NetBSD e Win32 :/
Sugestões são bem vindas.
Pac
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130514/e043acef/attachment.html>
More information about the SaoPaulo-pm
mailing list