Logo_objecttraining
Centro de treinamento Open Source
HOME INSTITUCIONAL PARCEIROS INSTRUTORES TREINAMENTOS ARTIGOS CONTATO
Performance, escalabilidade, ruby-vms e nossa experiência
Sem dúvida este é o ano da promessa para as Ruby Machines. Este assunto já me interessava, mas quando tivemos solucionar o problema de consumo de memória do site de um cliente em Ruby on Rails o assunto teve que ser estudado a fundo. Gargabe Collector, Tuning no Rails, etc. E não só isso, vários testes sobre o MRI (versão oficial do Ruby 1.8.6) e sobre o JRuby foram feitos a ponto de massacrar um servidor de testes. A partir dai ganhamos uma experiência nova, sempre aprendemos mais com os problemas e quero compartilhar essa experiência com você !

O problema !
Bom, tudo começou quando o servidor de um cliente que possue nosso ERP (que atualmente está 40% migrado para Rails), esteve com problemas de uso absurdo de memória. É um servidor Linux, e a swap chegava a ser usada a ponto de inviabilizar seu uso. Era uma daquelas situações que só dando um restart nos servidos resolveria o problema. Além do ERP o servidor possuia o E-commerce integrado a ele. Este totalmente escrito em Ruby on Rails.
 

Investigando...
Resolvi então examinar onde era o problema, e após colocar o site na minha máquina utilizei o monit (vou falar dele logo a frente) para verificar o consumo de memória. Com um script bem simples carregava a index do site várias vezes. E para minha surpresa o site em apenas 10 minutos ele consumia 100 mb. O mesmo site coloquei em nosso servidor de testes e após 44 minutos ele consumia 300 mega de swap. A máquina possuia 512 mb de ram.
 
Não havia dúvidas que o problema era o site, então criei um index em branco com um render :text => 'alguma coisa' e efetuei os testes. A memória simplesmente não subia. Minha idéia era verificar se havia algum prolbema com o mongrel ou alguma customização do rails feita por nós. Então depois de vários testes descobrimos os gargalos. Uma consulta no ActiveRecord fazia uma busca de Produto onde possuia vários relacionamentos e o pior é que o Produto possuia uma relação has_many (1 para muitos) para Preco e Estoque. O resultado de nossa consulta era perfeita para trabalharmos pois ele retorna uma instancia de produto que podiamos fazer produto.precos[0].custo, ou, produto.estoques[0].quantidade. E a consulta garantia que viria apenas um registro de Preco/Estoque.
 
Outro gargalo era uma consulta pelo ActiveRecord de Categoria e Sub-Categoria onde era feita um each dentro de outro each para localizar as categorias.
 

A solução !
Esta parte foi até simples, substituimos a consulta feita pelo ActiveRecor::Base.find, por uma em SQL. Mas também NÃO utilizamos find_by_sql. Por quê ? Porque em find_by_sql ele retorna uma instancia do objeto que você está consultando exemplo: Produto.find_by_sql "SELECT *...", o resultado é um array contendo nele instâncias de Produto. Caso exista um relacionamento de belongs_to ou has_many você não conseguirá acessar valores que na consulta sql tenham o mesmo nome do relacionamento, exemplo:

class Produto
has_many :estoque
end

Produto.find_by_sql "SELECT produto.id, estoque.quantidade as estoque"

O campo nomeado como estoque possue o mesmo nome do relacionamento assim eles "trobam", isso pode parecer contornável, mas em query extremamentes complexas isto sim pode gerar problemas.
 
Primeira_offAnterior_off 1 2  3  4  5  Proxima_onUltima_on
Contato
Rua Vitória, 395 - sala 910.
CEP: 01210-001
São Paulo - SP

Central de Atendimento:
(11) 3224-9198

Deixe dúvida, opinião ou crítica.
Clique Aqui

Mapa de Localização
Artigos
Performance, escalabilidade, ruby-vms e nossa experiência - 14/05/2008
Sem dúvida este é o ano da promessa para as Ruby Machines. Este assunto já me interessava, mas quando tivemos solucionar o...
Criando validates personalizados, exemplo com cpf e cnpj - 16/04/2008
Validates são muito fáceis de usar ! E gerar validates personalizados podem lhe poupar ainda mais tempo ! Neste artigo ve...
Acessando DLL'S no ruby (exemplo com ECF) - 07/04/2008
Ruby realmente é mais do que simplesmente programar para a web ! Eu mesmo somente decidi migrar todos os aplicativos da O...

Logo_jruby
"Rails", "Ruby on Rails", e o logotipo do Rails são marcas registradas de David Heinemeier Hansson, com todos os direitos reservados.
Todas as demais marcas registradas são propriedades de seus respectivos donos, com direitos reservados.