Instâncias Mastodon que crescem além de alguns milhares de usuários ativos frequentemente encontram um gargalo no banco de dados PostgreSQL primário. Operações pesadas de leitura, como carregar a linha do tempo federada, pesquisar postagens públicas e buscar perfis de usuários, consultam o mesmo servidor de banco de dados. Quando esse servidor não consegue acompanhar, o carregamento das páginas fica lento e os timeouts aumentam. Este artigo explica como configurar uma réplica de leitura PostgreSQL para uma instância Mastodon, aliviando a carga de consultas de leitura e melhorando os tempos de resposta.
Uma réplica de leitura é um banco de dados secundário que permanece sincronizado com o primário por meio de replicação de streaming. Os aplicativos Mastodon podem então rotear consultas somente leitura para a réplica, enquanto as gravações continuam no primário. Essa configuração não exige alterações no código-fonte do Mastodon — apenas mudanças de configuração no adaptador de banco de dados do Rails e na camada de proxy reverso. As etapas cobrem o provisionamento de um servidor de réplica, a configuração da replicação de streaming e a atualização do Mastodon para usar a réplica para escala de leitura.
Principais Conclusões: Configuração de Réplica de Leitura Postgres para Mastodon
- Replicação de streaming via pg_basebackup: Clona o banco de dados primário para um servidor secundário para aliviar consultas somente leitura.
- Variável de ambiente DATABASE_REPLICA_URL do Mastodon: Configura o Rails para rotear consultas SELECT para a réplica enquanto as gravações permanecem no primário.
- Alterações em pg_hba.conf e postgresql.conf: Habilitam conexões de replicação e definem wal_level como logical ou replica no servidor primário.
Por que o Mastodon Precisa de uma Réplica de Leitura Postgres
O Mastodon usa PostgreSQL como seu armazenamento de dados principal. Cada carregamento de página, chamada de API e trabalho em segundo plano consulta o banco de dados. Em uma instância movimentada, as consultas mais caras são aquelas que escaneiam tabelas grandes — a tabela de status, a tabela de contas e as visões materializadas da linha do tempo. Quando o servidor de banco de dados primário opera com alta utilização de CPU ou I/O, todas as operações ficam lentas, incluindo gravações que precisam ser rápidas para postagens e interações dos usuários.
Uma réplica de leitura resolve isso movendo o tráfego pesado de leitura para um servidor separado. A réplica executa a mesma versão do PostgreSQL e aplica as alterações do primário em tempo quase real. Os aplicativos Mastodon podem se conectar à réplica para instruções SELECT, enquanto todas as operações INSERT, UPDATE e DELETE continuam no primário. Isso reduz a contenção de bloqueios e distribui a carga de consultas entre dois servidores.
Pré-requisitos
Antes de iniciar a configuração, garanta que as seguintes condições sejam atendidas:
- Dois servidores rodando Ubuntu 22.04 ou Debian 12 com PostgreSQL 15 ou 16 instalado.
- O servidor primário tem pelo menos 4 GB de RAM e 2 núcleos de CPU. A réplica deve igualar ou exceder os recursos do primário.
- Ambos os servidores podem se comunicar por uma rede privada na porta 5432. Não exponha a réplica à internet pública.
- O Mastodon já está rodando no servidor primário com PostgreSQL 15 ou 16. A configuração assume Mastodon 4.2 ou posterior.
- Você tem acesso root ou sudo em ambos os servidores.
Passos para Configurar uma Réplica de Leitura Postgres para Mastodon
A configuração tem três fases: preparar o servidor primário, criar a réplica e configurar o Mastodon para usar a réplica para leituras.
Fase 1: Preparar o Servidor Primário para Replicação
- Edite o postgresql.conf no servidor primário
Abra o arquivo de configuração do PostgreSQL, geralmente localizado em /etc/postgresql/15/main/postgresql.conf. Defina os seguintes parâmetros:wal_level = replica
max_wal_senders = 3
wal_keep_size = 1024
Essas configurações habilitam dados WAL (write-ahead log) suficientes para serem enviados à réplica. Aumente max_wal_senders se você planeja adicionar mais réplicas. - Edite o pg_hba.conf para permitir conexões de replicação
Adicione uma linha ao pg_hba.conf que permita que o IP do servidor de réplica se conecte para replicação. Por exemplo:host replication replicator 192.168.1.20/32 md5
Substitua 192.168.1.20 pelo IP privado real do servidor de réplica. - Crie um usuário de replicação
Conecte-se ao banco de dados primário como usuário postgres e execute:CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'senha_forte';
Registre essa senha — você precisará dela no servidor de réplica. - Reinicie o PostgreSQL no primário
Execute sudo systemctl restart postgresql para aplicar as alterações de configuração.
Fase 2: Criar o Servidor de Réplica
- Instale o PostgreSQL no servidor de réplica
Use a mesma versão do PostgreSQL do primário. No Ubuntu 22.04, execute:sudo apt update && sudo apt install postgresql-15 - Pare o PostgreSQL na réplica
Execute sudo systemctl stop postgresql para garantir que não haja conflitos de dados existentes. - Remova o diretório de dados padrão na réplica
Execute sudo rm -rf /var/lib/postgresql/15/main/ para limpar o cluster de banco de dados padrão. - Clone o banco de dados primário usando pg_basebackup
Execute o seguinte comando como usuário postgres:pg_basebackup -h IP_PRIMARIO -D /var/lib/postgresql/15/main -U replicator -P -v --wal-method=stream
Substitua IP_PRIMARIO pelo IP privado do servidor primário. Digite a senha de replicação quando solicitado. - Crie um arquivo standby.signal
Execute touch /var/lib/postgresql/15/main/standby.signal para informar ao PostgreSQL para iniciar em modo standby. - Configure primary_conninfo no postgresql.conf na réplica
Adicione a seguinte linha ao /etc/postgresql/15/main/postgresql.conf:primary_conninfo = 'host=IP_PRIMARIO port=5432 user=replicator password=senha_forte sslmode=require'
Substitua o IP do host e a senha pelos seus valores reais. - Inicie o PostgreSQL na réplica
Execute sudo systemctl start postgresql. Verifique o arquivo de log em /var/log/postgresql/postgresql-15-main.log para o status da replicação. Você deve ver uma linha indicando que a réplica está transmitindo WAL do primário.
Fase 3: Configurar o Mastodon para Usar a Réplica para Leituras
- Adicione a variável de ambiente DATABASE_REPLICA_URL
Edite o arquivo de ambiente do Mastodon, geralmente localizado em /home/mastodon/live/.env.production. Adicione a seguinte linha:DATABASE_REPLICA_URL=postgresql://usuario_mastodon:senha@IP_REPLICA:5432/mastodon_production?sslmode=require
Substitua usuario_mastodon, senha, IP_REPLICA e mastodon_production pelas suas credenciais reais e nome do banco de dados. - Reinicie os serviços do Mastodon
Execute os seguintes comandos para reiniciar os processos web e de streaming:systemctl restart mastodon-web
systemctl restart mastodon-streaming
systemctl restart mastodon-sidekiq
O Mastodon agora roteia consultas de leitura para a réplica automaticamente. - Verifique se a réplica está recebendo consultas
Conecte-se ao banco de dados da réplica e execute:SELECT count() FROM pg_stat_activity WHERE state = 'active';
Você deve ver conexões do servidor de aplicação Mastodon.
Se a Réplica Falhar ao Iniciar ou Sincronizar
Problemas de replicação podem impedir que a réplica inicie ou fazer com que ela fique atrasada em relação ao primário. Abaixo estão os padrões de falha mais comuns e suas correções.
Réplica Falha ao Iniciar com “FATAL: could not connect to the primary server”
Esse erro significa que a réplica não consegue alcançar o servidor primário na porta 5432. Verifique se o firewall do servidor primário permite conexões de entrada do IP da réplica. No primário, execute sudo ufw status para confirmar que a porta 5432 está aberta. Também verifique se a string primary_conninfo no postgresql.conf da réplica usa o endereço IP e a senha corretos.
Atraso de Replicação Aumenta ao Longo do Tempo
Alto volume de gravação no primário pode fazer com que a réplica fique atrasada. Monitore o atraso com a consulta SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) FROM pg_stat_replication; no primário. Se o atraso exceder 100 MB, aumente wal_keep_size no primário ou adicione mais recursos à réplica. Também garanta que a réplica tenha largura de banda de I/O de disco suficiente — use armazenamento SSD se possível.
Mastodon Ainda Mostra Consultas Lentas Após Adicionar a Réplica
Se o Mastodon continuar com carregamento lento de páginas, verifique se a variável de ambiente DATABASE_REPLICA_URL está configurada corretamente. Execute echo $DATABASE_REPLICA_URL no servidor de aplicação Mastodon para confirmar. Também verifique se o banco de dados da réplica tem os mesmos índices que o primário. Execute vacuumdb e reindex periodicamente na réplica para manter o desempenho das consultas.
Primário vs Réplica: Comparação de Configuração para Mastodon
| Item | Servidor Primário | Servidor de Réplica |
|---|---|---|
| Propósito | Lida com todas as gravações e leituras críticas | Lida com consultas somente leitura do Mastodon |
| Modo PostgreSQL | Leitura-gravação | Standby (somente leitura) |
| wal_level | replica ou logical | hot_standby (padrão) |
| String de conexão no Mastodon | DATABASE_URL | DATABASE_REPLICA_URL |
| Método de backup | pg_dump ou arquivamento WAL | pg_basebackup do primário |
| Capacidade de failover | Pode ser promovido a primário | Não usado para failover nesta configuração |
Agora você tem uma réplica de leitura PostgreSQL funcional para sua instância Mastodon. A réplica lida com consultas SELECT dos processos web e de streaming, reduzindo a carga no primário. Monitore o atraso de replicação diariamente usando a visão pg_stat_replication. Como próximo passo, considere adicionar um pooler de conexões como PgBouncer na frente do primário e da réplica para gerenciar conexões de banco de dados de forma eficiente. Para configurações avançadas, configure pg_rewind para habilitar failback rápido se o primário precisar ser reconstruído a partir da réplica.