segunda-feira, 1 de dezembro de 2014

Instalando MongoDB na AWS

E ai pessoal, tudo bem?

Em meu último post aqui no blog falei sobre a criação de Replica Sets com o MongoDB. Na época estava passando por problemas com a performance das consultas no banco e imaginava que a melhor saída seria a criação de um Replica Set para distribuir as leituras nessa estrutura, porem eu estava enganado e hoje venho aqui compartilhar com vocês algumas coisas que aprendi nesse ínterim.



Instalação


No meu caso a instalação do MongoDB é feita em um servidor virtual da Amazon, como mencionei no post anterior, o EC2. Nesse ambiente é possível provisionar a velocidade dos discos (chamados EBS) através da configuração dos IOPS, que em tradução livre seria a quantidade de operações de I/O por segundo, e para o MongoDB quanto mais rápido o disco, melhor! Porem, um detalhe importante é que não adianta apenas configurar o disco com muitos IOPS, é preciso pré aquece-lo!

A operação de pre-aquecimento, ou pre-warming, se faz necessária apenas na inicialização do disco, seja um disco novo ou um disco criado a partir de uma imagem. Sem esse preparo o disco pode ficar de 5 a 50% mais lento (sim, até 50% mais lento o.O) e esse foi um dos fatores que me fez sofrer com a performance das consultas, com certeza. Você pode ler mais sobre o pré-aquecimento na documentação da Amazon mas ele consiste em desmontar (umount) o disco e executar o seguinte comando:

sudo dd if=/dev/zero of=/dev/xvdf bs=1M

Substitua a unidade em vermelho pela unidade que esta usando e espere, o comando pode levar algumas horas para terminar dependendo o tamanho do disco. Uma boa ideia é usar o screen para não perder o trabalho se a sessão cair.

Outro ponto muito importante para a performance do MongoDB e que independe da hospedagem usada é a configuração do ulimit do sistema. A maioria dos sistemas Linux vem configurado por padrão para impedir que um usuário ou processo consuma demais os recursos do servidor mas as vezes esses limites são muito baixos e interferem na performance do MongoDB. Você pode ler mais a respeito na documentação da 10gen mas a recomendação é a seguinte:

- file size: unlimited
- cpu time: unlimited
- virtual memory: unlimited
- open files: 64000
- memory size: unlimited
- processes/threads: 64000

Com essas duas configurações fui capaz de melhorar drasticamente a performance da minha instalação de MongoDB, então acredito que essas dicas podem ajudar a todos.

Alocação de hardware


Outro ponto que percebi ser muito importante para a performance do MongoDB é escolher o servidor certo. Quando comecei a lidar com esse banco de dados acreditava que o disco seria o recurso mais importante e, apesar de não estar totalmente errado, hoje vejo que a memória RAM é a mais importante. Durante o funcionamento do banco, caso não haja memória RAM o bastante será necessário fazer muitas trocas de conteúdo em memória, aumentando o uso do disco e prejudicando a performance. A recomendação é para que pelo menos os índices caibam em memória, você pode ver isso com o comando status presente em cada coleção, no console do MongoDB:

> db.sua_colecao.stats()

O comando vai te mostrar o tamanho de cada índice em bytes, ai é só somar e ver se cabe na memória RAM.

Para quem usa AWS, foi lançado um novo tipo de instancia EC2 com otimização de memória, as instancias R3. Elas são uma ótima opção para o MongoDB como é apresentado neste artigo do mongodirector.

Versão do MongoDB


Nem preciso dizer aqui os diversos motivos para usarmos sempre as versões mais novas dos sistemas, mas no caso do MongoDB existem questões importantes para nossa discussão. Em meu último post a versão vigente era a 2.4 e nela os locks do banco eram globais, isso quer dizer que qualquer operação de escrita bloqueava o banco de dados completamente e nenhuma outra escrita poderia ser feita. Na versão 2.6 os locks passaram a ser no nível do database, portanto passou a ser possível fazer escritas e leituras simultaneamente em databases diferentes. Na versão 2.8, segundo esse post no blog do MongoDB, os locks serão no nível do documento o que terá grande impacto na performance no sistema.

Estou bastante ansioso para que saia logo a versão final do MongoDB 2.8 pois tenho certeza que esse upgrade terá grande impacto na performance e me ajudará muito! =D

Espero que tenham gostado do post! Dúvidas, criticas e sugestões são sempre bem vindos!

Um abraço e até a próxima!