Réplica Postgres para Escala de Leitura no Mastodon: Configuração
🔍 WiseChecker

Réplica Postgres para Escala de Leitura no Mastodon: Configuração

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.

ADVERTISEMENT

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

  1. 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.
  2. 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.
  3. 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.
  4. 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

  1. 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
  2. Pare o PostgreSQL na réplica
    Execute sudo systemctl stop postgresql para garantir que não haja conflitos de dados existentes.
  3. 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.
  4. 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.
  5. Crie um arquivo standby.signal
    Execute touch /var/lib/postgresql/15/main/standby.signal para informar ao PostgreSQL para iniciar em modo standby.
  6. 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.
  7. 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

  1. 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.
  2. 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.
  3. 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.

ADVERTISEMENT

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.

ADVERTISEMENT