As emocionantes aventuras de um sysadmin linux na procura pelo uptime perfeito!

Anunciando o HoardD, ferramenta para envio de métricas para o Graphite

Posted: fevereiro 10th, 2012 | Author: coredump | Filed under: Linux e Open Source, Programação

HoardD é um projeto usando Node.js para enviar métricas de servidores para o Graphite. Você pode ler o anúncio no meu blog em inglês: http://coredump.io/blog/2012/02/10/announcing-hoardd/

intel!

No Comments »

MongoDB: sharding e mapReduce()

Posted: novembro 14th, 2010 | Author: coredump | Filed under: Linux e Open Source, Programação | Tags: , , ,

Uma das coisas interessantes que me atraiu a testar o MongoDB foram as capacidades de sharding e replicação do mesmo. Sharding é uma técnica muito usada atualmente para lidar com escalabilidade de massas de dados, consiste basicamente em dividir os dados de uma aplicação entre vários bancos: por exemplo, numa aplicação com 1000 usuários o sharding faria que os usuários com nomes de A a J ficassem em um servidor, e de K a Z em outro servidor. Claro que tem mais coisas envolvida, recomendo a leitura do excelente artigo Sharding for startups que discute como particionar os dados e como fazer aplicações que suportam sharding.

O MongoDB é um banco de dados não SQL que tem ganhado espaço. Foursquare por exemplo usa o Mongo com uma massa de dados razoável (3 shards de 60Gb, de acordo com uma informação já um pouco desatualizada). Nas versões mais recentes, o MongoDB também ganhou suporte nativo a sharding e uma replicação mais robusta.

Bancos NoSQL como  Mongo tem grandes diferenças com os RDB existentes. A mais importante, SQL não existe, então algumas coisas como SELECT SUM() ou SELECT … GROUP BY que se está acostumado a usar tem de ser implementados de outra forma. As vezes é melhor implementar todo esse tratamento na aplicação, mas no caso do MongoDB ele possui uma implementação de Map/Reduce nativa, exatamente para se fazer esse tipo de tratamento de dados. Um detalhe interessante na performance deste sistema é que no caso de bancos com shards o trabalho é dividido entre os mesmos.

Para testar o ganho de performance e se a divisão era feita corretamente, fiz o seguinte teste: habilitei sharding em uma collection com dados de logs com 19 milhões de registros, cada registro com tamanho entre 150 e 220 bytes. Usei as seguintes funções para o Map/Reduce:

Função de mapeamento (map):

function m() {
	emit(this.c, {duration: this.d,
			size: this.s,
			conn: 1});
}

Função de redução (reduce):

function r(key, val) {
	var total_duration = 0;
	var total_size = 0;
	var total_conn = 0;
	for (var i = 0; i < val.length; i++) {
		total_duration += val[i].duration;
		total_size += val[i].size;
		total_conn += 1;
	}
	return {duration: total_duration,
			size: total_size,
			total_conn : total_conn };
}

O balanceamento dos dados entre os dois shards que eu criei demorou quase três horas, nesse tempo o banco continua disponível exceto por updates em dados que estão no processo de serem movidos para outro shard. Depois de terminado esse processo eu tinha dez milhões de registros no servidor original e os outros nove milhões e qualquer coisa no segundo shard.

O processo de Map/Reduce com apenas um banco demorou 15 minutos para completar, agindo sobre todos os registros. Depois do sharding, esse tempo caiu pela metade indo para 7 minutos. Se a melhora for sempre nesta proporção a adição de shards implica diretamente na divisão do tempo do processamento pelo número de shards envolvidos. De acordo com a equipe de desenvolvimento do MongoDB eles estão trabalhando agora para melhorar o paralelismo da operação de Map/Reduce mas aparentemente isso depende da engine que eles usam para interpretar o javascript das funções.

O sharding do MongoDB é bem implementado, mas tem de se ter cuidado na hora de escolher a chave pela qual ele vai fazer a divisão dos dados. Uma chave mal escolhida pode fazer com que os shards fiquem mal balanceados e acabe com todo o ganho de performance que teria sido conseguido. Um exemplo seria se no meu teste eu tivesse acabado com um milhão de records em um dos shards, e os outros dezoito no outro: os resultados estariam disponíveis no shard com menos data muito antes do outro terminar.

intel

No Comments »

Ftrace – tracing de funções do kernel Linux

Posted: novembro 10th, 2010 | Author: coredump | Filed under: Linux e Open Source, Programação | Tags: , , ,

Saiu um artigo sobre o assunto na LWN a alguns meses atrás, o function tracer do Kernel tá uma coisa linda. Basicamente a ferramenta é colocada diretamente no kernel para fazer tracing do que está acontecendo no kernel.

Eu tenho por exatamente usado para estudar internals. Por exemplo:

[tracing]# cat trace
          <idle>-0     [000] 1726568.996435: hrtimer_get_next_event <-get_next_timer_interrupt
          <idle>-0     [000] 1726568.996436: _spin_lock_irqsave <-hrtimer_get_next_event

Essa saída aí em cima mostra a thread idle (swapper), PID 0, rodando na CPU 0, timestamp de quando a função foi executada e as funções que estão rodando. Existem várias configurações que podem ser feitas, como por exemplo adicionar informações de latência no tracing. Isso faz com que além dos timestamps sejam colocadas as informações de quanto tempo cada função demorou para executar.

Eu escrevi um scriptizinho em bash para facilitar minha vida ao ligar e desligar o tracing. Na minha máquina funcionou beleza (ainda tem bugs, mas funciona), mas lembre-se que alguns tracers (como o function) tem de ser habilitados no Kernel e pelo menos no kernel do Debian não estavam. Como eu já estava recompilando o 2.6.36 para fazer alguns testes, aproveitei para habilitar.

O Perfikt é uma ferramenta  GTK que usa dados do Valgrind e aparentemente tem suporte para a interface de tracing do kernel, fornecendo uma interface gráfica bem simpática para a parada.

Mais sobre o assunto (em inglês):

intel

No Comments »

VULoad, para observar load average em terminais

Posted: outubro 5th, 2010 | Author: coredump | Filed under: Linux e Open Source, Programação | Tags: , ,

Update: dei uma mexida nele e já coloquei a versão nova no github. Agora ele parece um pouco mais rápido para sair. Atualizei o screenshot também (os mais atentos vão notar que as barras estão sendo desenhadas com dados de teste, bem mais altos que os loads mostrados no cabeçalho).

Nesse final de semana de eleição tivemos de colocar umas coisas no ar na EBC para atender as demandas de infraestrutura dos sistemas suportando as rádios, agência de notícias, apuração em tempo real e tv ao vivo, e para isso fizemos vários testes incluíndo balanceamento e carga. Num desses um dos colegas do desenvolvimento me sacaneou porque eu estava usando os gráficos do Zabbix para monitorar o load dos servidores, enquanto usava o iftop em um terminator todo repartido para ver como andava a rede dos mesmos.

Como nada é mais inspirador que uma boa aporrinhação-construtiva, tirei um tempo nas madrugadas para fazer um trequinho em python-ncurses para a próximas vez que eu precisar monitorar o Load Average de máquinas em modo console. Na verdade, eu imagino que já exista, mas como eu ando precisando reanimar meus skills em python eu nem me esforcei muito para procurar. Abaixo dois screenshots da paradinha em funcionamento:

Essa é minha máquina local, com quatro processadores e pouco load. Não tinha nada a mão para gerar um bom enfileiramento de processos então ficou assim mesmo.

A idéia é a seguinte: até o meio da tela eu mostro uma barra linear que vai até o valor de Load Average igual ao número de CPUs disponíveis na sua máquina (ou seja, até onde o seu Load Average está tranquilo, leia isso aqui para entender). Depois disso eu uso um multiplicador configurável (no código claro) para mostrar a barra de excesso de load. Visualmente é fácil de interpretar, mesmo se estiver com vários abertos na: se a barra passou do meio da tela o load está alto demais e processos estão começando a enfileirar, quanto mais pro final da tela, pior.

Ainda tem algumas coisinhas cosméticas para mexer, e eu ainda tenho de testar em uma máquina com load alto de verdade, para ver como ele se comporta (por exemplo, se ele vai conseguir se atualizar corretamente com um grande enfileiramento acontecendo).

Mais um screenshot, agora usando o terminator para mostrar duas telas simultâneas, no meu VPS que só tem uma CPU:

O código está no Github, você pode baixar direto clicando aqui. Obviamente, é GPL. É um bom exemplo de como usar ncurses com python também, para quem quiser ter um feeling de como era programar na era dos terminais. Por exemplo, eu tinha me esquecido como era ter de se lembrar de re-escrever a tela. Ou fazer barras usando código ASCII. Mas foi bem divertido. Vou dar mais umas hackeadas nele depois se pensar em mais informações ou alguma otimização que for interessante de fazer.

intel.

No Comments »

(quase) Trocando o Prism por um script de 60 linhas

Posted: outubro 6th, 2009 | Author: coredump | Filed under: Linux e Open Source, Programação | Tags: , , , , ,

Quase, mas quase mesmo.

O Prism é o antigo xulrunner da Mozilla. Básicamente é um browser capado para rodar aplicações web em janelas separadas do browser normal. Assim se a aplicação trava você não perde o browser, ou vice e versa. Eu uso bastante para rodar o gmail, o webmail do trabalho e o brizzly. O problema é que o treco é muito bloated. E da uns paus muito bizarros com SSL. E usa Gecko e mais uma estrutura gigante do Firefox por trás que não é bem necessário ao que ele se propõe.

Como o kov é minha musa inspiradora, resolvi dar uma fuçada no PyWebkitGTK e acabei escrevendo uma coisinha semi funcional em 60 linhas de Python :P . Chamei o script de prisw, tipo, Prism com o M invertido vira W de WebKit. Ta-dã.

A parte mais importante tá aí: ele lê arquivos de configuração e roda em janelas separadas. Eu só não parei de usar o Prism ainda porquê preciso:

  1. Colocar o código para que links clicados sejam passados para o OS (eu não quero abrir janelas e urls dentro da mesma app)
  2. Tratar o título da janela com relação a mudanças que acontecem no TITLE das páginas (gmail e brizzly fazem isso)
  3. Talvez colocar uma opção para mostrar uma barra de status, nem que seja para mostrar se o SSL está ativo
  4. Lidar com cookies. Atualmente, mesmo que eu peça para guardar informações de login/etc, essas infos não tem onde serem salvas.

O WebKit que eu estou usando tem alguns probleminhas também com dimensionamento de janela, mas parece que já estão resolvendo no upstream. Daqui umas 2 semanas eu revisito o código e quem sabe eu posso parar de usar Prism, e ainda ganhar as vantagens do WebKit (velocidade, javascript violentamente rápido, etc…).

Aliás, tenho de dizer que optparser e configparser fazem a vida ficar extremamente simples ao se lidar com linhas de comando e arquivos de configuração em python viu.

Sintam-se livres para baixar e fuçar o script, ele é GPL, claro.

intel

No Comments »