Carlos Brando

Nome do Jogo

Edge Rails: Pool de Conexões no Rails

Algo que muita gente reclama sobre o Rails é que ele é lento. Sabemos que isto não é totalmente verdade, mas também sabemos que muita coisa pode ser feita para melhorar a performance dele.

Uma destas coisas acabou de se feita. Foi incluído ao Rails um Pool de Conexões com o banco de dados.

Toda vez que uma requisição ao banco de dados é feita, perde-se algum tempo criando uma nova conexão e só depois é que a pesquisa ou gravação é realizada. Olhando superficialmente pode parecer algo muito rápido e simples, mas abrir uma conexão com o banco de dados não é tão simples assim. É necessário estabelecer uma conexão física com o servidor do banco, autenticar a conexão e realizar mais uma série de validações. Tudo isto consome recursos e tempo. Isto explica muito bem o porque de o banco de dados se tornar o vilão de alguns grandes projetos criados em Rails.

A solução para este tipo de problema é reaproveitar conexões já criadas para realizar mais tarefas dentro do banco de dados antes de fecha-las. Ou em termos mais técnicos, precisamos de um Pool de Conexões.

O processo é o seguinte: Uma conexão com o banco de dados é aberta e utilizada para realizar uma pesquisa. Depois disso, ao invés de fecha-la, ela é armazena no pool de conexões. Quando uma outra requisição é feita, ao invés de abrir uma nova conexão, o sistema reaproveita uma que já foi aberta, diminuindo o tempo e os recursos necessários para realizar a tarefa. Várias conexões podem ser armazenadas no pool ao mesmo tempo.

No Rails será criado um novo pool para cada execução do método establish_connection. Em outras palavras, cada banco de dados cadastrado no arquivo database.yml terá seu próprio pool de conexões.

O pool começa vazio e vai crescendo até o limite de 5 conexões (padrão), mas você pode aumentar este limite acrescentando a opção ’pool’ na configuração do banco de dados.

development:
  adapter: mysql
  host: localhost
  username: myuser
  password: mypass
  database: somedatabase
  pool: 10
  wait_timeout: 15

Se nenhuma das conexões estiver disponível, uma thread irá esperar durante 5 segundos (padrão) e tentar novamente. Este tempo também pode ser configurado adicionando a chave ’wait_timeout’ na configuração do banco de dados.

Se você desejar usar o pool de conexões fora do ActionPack, existe o método ActiveRecord::Base.connection_pool que permite que você manualmente faça o checkout/checkin das conexões. Não esqueça de fazer o checkin quando terminar de usar a conexão.

connection = ActiveRecord::Base.connection_pool.checkout

# faz alguma coisa no banco de dados

ActiveRecord::Base.connection_pool.checkin(connection)

Você também pode usar o método ActiveRecord::Base.connection_pool.with_connection que já faz o checkout/checkin automaticamente para você, tornando-se uma opção mais segura.

ActiveRecord::Base.connection_pool.with_connection do |connection|
  # faz alguma coisa no banco de dados
end

Comments