A separação entre operações de leitura e escrita em bancos de dados é uma técnica essencial para otimizar aplicações Rails orientadas a API. Ao distribuir consultas entre servidores diferentes, é possível reduzir gargalos e melhorar a latência das respostas.
Fundamentos da Separação Leitura/Escrita
Em cenários onde as requisições de leitura superam as de escrita — comum em APIs RESTful —, redirecionar queries de leitura para réplicas do banco principal alivia a carga do servidor primário. Isso resulta em maior throughput e melhor aproveitamento dos recursos de hardware.
Configuração Inicial do Banco de Dados
O primeiro passo envolve ajustar o arquivo config/database.yml para definir conexões distintas para o servidor principal e a réplica:
production:
primary_db:
adapter: postgresql
database: app_prod
username: app_user
password: <%= ENV['DB_MAIN_PASS'] %>
host: db-main.exemplo.com
replica_db:
adapter: postgresql
database: app_prod
username: readonly_user
password: <%= ENV['DB_REPLICA_PASS'] %>
host: db-replica.exemplo.com
replica: true
Vincualndo Modelos às Conexões
Com as conexões definidas, é preciso instruir o Active Record sobre qual banco usar para cada papel. Isso é feito na classe base dos modelos:
class ApplicationModel < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :primary_db, reading: :replica_db }
end
Automaticamente, o Rails passará a encaminhar operações de escrita (INSERT, UPDATE, DELETE) para o servidor primário e operações de leitura (SELECT) para a réplica.
Controle Manual de Conexões
Em situações específicas, pode ser necessário forçar o uso de um servidor particular. O método connected_to permite esse controle granular:
# Forçar leitura no banco primário para dados críticos
Account.connected_to(role: :writing) do
Account.find_by(token: 'abc123')
end
# Utilizar réplica para listagens pesadas
Post.connected_to(role: :reading) do
Post.where(published: true).limit(50)
end
Desafios Comuns
Latência de replicação: Réplicas podem ter um atraso na sincronização. Para dados sensíveis, leia diretamente do primário ou implemente verificações de consistência.
Indisponibilidade da réplica: É recomendável implementar mecanismos de fallback que redirecionem leituras para o banco principal caso a réplica esteja inacessível, evitando interrupções no serviço.