Instância do Mastodon Lenta ao Carregar a Linha do Tempo Federada: Causas
🔍 WiseChecker

Instância do Mastodon Lenta ao Carregar a Linha do Tempo Federada: Causas

Quando você abre a linha do tempo federada no Mastodon, as postagens podem levar vários segundos ou até minutos para aparecer. Esse atraso torna a navegação no feed público frustrante, especialmente em instâncias grandes. A principal causa é o enorme volume de dados que o servidor precisa buscar, filtrar e exibir de outras instâncias no fediverso. Este artigo explica por que os feeds federados carregam lentamente e quais fatores técnicos contribuem para a demora.

As instâncias do Mastodon não pré-carregam toda a linha do tempo federada para cada usuário. Em vez disso, o servidor consulta seu banco de dados interno em busca de postagens públicas de instâncias conhecidas sob demanda. Quando esse banco de dados é grande ou o hardware do servidor é limitado, a consulta pode ser lenta. Este artigo aborda os motivos técnicos específicos por trás do carregamento lento da linha do tempo federada e como o tamanho da instância, o desempenho do banco de dados e a latência de rede desempenham um papel.

Principais Conclusões: Por que a Linha do Tempo Federada Carrega Lentamente

  • Atraso no processamento da fila Sidekiq: Novas postagens de instâncias remotas aguardam em uma fila de trabalhos antes de serem armazenadas no banco de dados local, atrasando a disponibilidade na linha do tempo.
  • Desempenho de consultas PostgreSQL em tabelas grandes: Instâncias com milhões de status fazem com que o mecanismo do banco de dados examine mais linhas, aumentando o tempo de resposta da consulta para renderização da linha do tempo.
  • Latência de rede entre instâncias: Buscar postagens de servidores remotos distantes ou sobrecarregados adiciona tempo de ida e volta antes que o conteúdo apareça no feed federado local.

Por que a Linha do Tempo Federada Sofre com Carregamento Lento

A linha do tempo federada é uma visão ao vivo de postagens públicas de todas as instâncias que sua instância conhece. O Mastodon armazena essas postagens em uma única tabela de banco de dados chamada statuses. Quando você abre a linha do tempo federada, o aplicativo web do Mastodon envia uma solicitação para o endpoint da API do servidor /api/v1/timelines/public. O servidor então executa uma consulta SQL na tabela statuses, filtrando por postagens públicas e ordenando por created_at decrescente.

Em uma instância pequena com menos de 10.000 status no total, essa consulta é concluída em menos de 100 milissegundos. Em uma instância grande com 1 milhão ou mais status, a mesma consulta pode levar de 2 a 5 segundos. O atraso é causado pelo mecanismo do banco de dados ao examinar um índice grande para encontrar as postagens mais recentes. Sem a indexação adequada do banco de dados ou RAM suficiente, a consulta se torna o principal gargalo.

Outro fator é a fila de trabalhos em segundo plano do Sidekiq. Quando uma instância remota envia uma nova postagem via ActivityPub, a instância receptora não a insere imediatamente na tabela statuses. Em vez disso, a postagem entra em uma fila do Sidekiq. Se a fila estiver acumulada com muitos trabalhos, a postagem pode levar minutos para aparecer na linha do tempo federada. A configuração padrão de concorrência do Sidekiq de 25 threads em um único núcleo de CPU pode rapidamente ficar sobrecarregada em instâncias que atendem milhares de usuários ativos.

Indexação do Banco de Dados e Otimização de Consultas

O Mastodon usa PostgreSQL com o índice btree na coluna statuses.created_at. Esse índice ajuda o banco de dados a encontrar postagens recentes rapidamente. No entanto, à medida que a tabela cresce, o próprio índice se torna maior e mais lento de percorrer. Um índice ausente ou desatualizado em statuses.visibility e statuses.local pode forçar o banco de dados a filtrar postagens públicas após examinar todo o índice, dobrando o tempo de consulta.

Os administradores de instância podem verificar o desempenho das consultas usando EXPLAIN ANALYZE na consulta da linha do tempo. Se a consulta mostrar uma varredura sequencial em vez de uma varredura de índice, o banco de dados está lendo todas as linhas da tabela. Esta é a causa mais comum de lentidão na linha do tempo federada em instâncias antigas que nunca executaram VACUUM ou ANALYZE.

Latência de Rede e Tempos de Resposta de Instâncias Remotas

O Mastodon não busca postagens de instâncias remotas em tempo real. Em vez disso, ele depende da instância remota enviar atualizações via requisições HTTP POST para o endpoint da caixa de entrada da instância local. Se a instância remota estiver geograficamente distante ou executando em hardware de baixa largura de banda, a entrega do payload ActivityPub pode levar vários segundos. Durante horários de pico, a instância remota pode enfileirar entregas de saída, adicionando mais atraso.

A instância local também consulta periodicamente instâncias remotas por postagens de contas que segue. Esse intervalo de consulta é controlado pela variável de ambiente FETCH_REMOTE_STATUSES, cujo padrão é 15 minutos. Se uma instância remota ficar temporariamente inacessível, a instância local tenta a conexão novamente até 5 vezes com backoff exponencial. Cada tentativa adiciona de 30 segundos a 2 minutos de atraso antes que a postagem apareça na linha do tempo federada.

Passos para Diagnosticar e Melhorar a Velocidade de Carregamento da Linha do Tempo Federada

Antes de tentar qualquer correção, confirme se a lentidão é específica da linha do tempo federada e não de toda a instância. Abra a linha do tempo inicial e um feed de hashtag local. Se eles carregarem instantaneamente, o problema está isolado na linha do tempo federada. Os passos a seguir ajudam a identificar o gargalo exato.

  1. Verifique a profundidade da fila do Sidekiq
    Abra um terminal no servidor Mastodon. Execute sudo docker exec mastodon_sidekiq_1 sidekiqmon ou sudo -u mastodon sidekiqmon se estiver usando pacotes do sistema. Observe o tamanho da fila default. Se exceder 5000 trabalhos, a fila está acumulada. Uma profundidade alta de fila significa que novas postagens esperam mais tempo antes de serem armazenadas no banco de dados.
  2. Revise o desempenho das consultas PostgreSQL
    Conecte-se ao banco de dados do Mastodon com sudo -u postgres psql mastodon_production. Execute EXPLAIN ANALYZE SELECT id, created_at FROM statuses WHERE visibility = 0 AND local = false ORDER BY created_at DESC LIMIT 20;. Procure por Seq Scan na saída. Se presente, a consulta não está usando um índice. Execute VACUUM ANALYZE statuses; para atualizar as estatísticas e reabilitar o uso do índice.
  3. Verifique a latência de rede para as principais instâncias remotas
    Identifique as instâncias remotas que enviam mais postagens para sua linha do tempo federada. Use curl -w '%{time_total}' -o /dev/null -s https://instancia.remota/api/v1/instance para medir o tempo de resposta. Se o tempo exceder 2 segundos, essa instância remota é um gargalo. Considere bloquear ou limitar essa instância através do painel de moderação.
  4. Aumente a concorrência do Sidekiq
    Edite o arquivo de ambiente do Mastodon .env.production. Defina SIDEKIQ_CONCURRENCY=50 se o servidor tiver pelo menos 4 núcleos de CPU. Reinicie o Sidekiq com systemctl restart mastodon-sidekiq. Uma concorrência maior permite que mais postagens sejam processadas simultaneamente, reduzindo o tempo de espera na fila.
  5. Adicione um índice composto na tabela statuses
    Como superusuário do banco de dados do Mastodon, execute CREATE INDEX CONCURRENTLY IF NOT EXISTS index_statuses_on_visibility_and_local_and_created_at ON statuses (visibility, local, created_at DESC);. Esse índice permite que o PostgreSQL recupere postagens públicas não locais em ordem classificada sem examinar toda a tabela. O tempo de consulta pode cair de segundos para menos de 50 milissegundos.

Se o Mastodon Ainda Tiver Problemas Após a Correção Principal

Linha do Tempo Federada Mostra Postagens Antigas Primeiro

Quando o índice do banco de dados está ausente ou a consulta usa uma varredura sequencial, a linha do tempo pode retornar postagens de semanas atrás antes de mostrar as recentes. Isso acontece porque o PostgreSQL classifica todo o conjunto de resultados na memória após a varredura, o que para tabelas grandes pode levar vários segundos. A correção é o índice composto do passo 5 acima. Após criar o índice, execute ANALYZE statuses; para atualizar o planejador de consultas.

Fila do Sidekiq Cresce Mais Rápido do que Processa

Se a fila do Sidekiq continuar crescendo mesmo após aumentar a concorrência, a CPU ou RAM do servidor está saturada. Use htop para verificar o uso da CPU. Se todos os núcleos estiverem em 100%, o hardware do servidor não suporta a carga da instância. A única correção de longo prazo é atualizar para um servidor com mais núcleos de CPU ou reduzir o número de usuários ativos limitando os cadastros.

Linha do Tempo Federada Carrega no Navegador, mas Não em Aplicativos de Terceiros

Aplicativos de terceiros podem usar um endpoint de API diferente que aplica filtros adicionais. Por exemplo, o aplicativo Tusky para Android usa /api/v1/timelines/public?local=false&only_media=false. Se o servidor tiver um limite de taxa ou um middleware personalizado que bloqueia requisições que não sejam do navegador, o aplicativo vê um timeout. Verifique os logs do proxy reverso do Mastodon (nginx ou Apache) em busca de respostas 429 ou 503 para o endpoint da API.

Desempenho da Instância Mastodon: Linha do Tempo Federada vs Linha do Tempo Inicial

Item Linha do Tempo Federada Linha do Tempo Inicial
Fonte de dados Todas as postagens públicas de todas as instâncias remotas conhecidas Postagens de contas que o usuário segue mais impulsionamentos dessas contas
Complexidade da consulta ao banco de dados Varredura completa da tabela statuses filtrada por visibilidade e flag local Busca indexada nas tabelas de seguidores e statuses usando o ID do usuário
Tempo típico de consulta em instância grande 2–5 segundos Abaixo de 200 milissegundos
Capacidade de cache Não pode ser armazenado em cache por usuário devido ao conteúdo remoto variável Armazenável em cache por usuário por até 60 segundos
Gargalo principal Índice do banco de dados e profundidade da fila do Sidekiq Número de seguidores e desempenho de junção do banco de dados

Após diagnosticar a causa, você pode aplicar a correção de indexação do banco de dados e ajustar a concorrência do Sidekiq para reduzir o tempo de carregamento da linha do tempo federada. Monitore a profundidade da fila do Sidekiq diariamente usando um cron job que registra o tamanho da fila. Se a fila permanecer abaixo de 1000 trabalhos, a instância pode lidar com a carga atual. Para lentidão persistente, considere ativar a variável de ambiente LIMITED_FEDERATION_MODE para restringir de quais instâncias remotas sua instância aceita postagens, o que reduz o número total de status no banco de dados.