58 pontos por GN⁺ 2025-07-23 | 3 comentários | Compartilhar no WhatsApp
  • Compartilha uma experiência real de rastrear 1 bilhão de páginas web em 24 horas e o processo de projetar um sistema moderno de web crawling
  • Com hardware recente e infraestrutura em nuvem, tornou possível o crawling em larga escala com custos na casa de algumas centenas de dólares, confirmando que o principal gargalo era o parsing
  • Mesmo sem executar JavaScript e fazendo apenas parsing de HTML, ainda foi possível acessar uma parcela significativa das páginas web
  • Projetou uma arquitetura de cluster de nós baseada em Redis e maximizou a eficiência com sharding por domínio e otimização da estrutura dos processos
  • Em vez da rede, os principais gargalos apareceram em CPU, SSL e memória, e o gerenciamento do frontier de grandes domínios foi a questão central

Definição do problema

  • Foi definida a meta de rastrear 1 bilhão de páginas web em 24 horas
  • O orçamento era de algumas centenas de dólares (cerca de 462 dólares no total), em nível semelhante ao do caso de 2012
  • Coletava apenas HTML, sem executar JavaScript, extraindo somente links <a>
  • Forte foco em politeness (crawling responsável): respeito ao robots.txt, inclusão de informações de User Agent, exclusão de domínios sob solicitação, alvo restrito aos 1 milhão de domínios mais populares e espera de 70 segundos para o mesmo domínio
  • Garantiu tolerância a falhas: em caso de falha de nós, aceitava reinicialização e alguma perda de dados, adotando uma abordagem baseada em amostragem

Arquitetura e projeto

  • Diferentemente do estilo tradicional de entrevista de system design, com distribuição por função, foi escolhida uma estrutura em que cada nó processa por conta própria todas as funções (estado do crawler, parsing, fetch, armazenamento etc.)
  • 12 nós, cada um usando uma instância i7i.4xlarge (16 vCPU, 128GB RAM, 10Gbps, 3750GB de armazenamento)
  • Cada nó era composto por 1 Redis, 9 fetchers e 6 processos de parser
  • No Redis eram armazenados frontier por domínio, fila de fetch, URLs visitadas, Bloom filter, robots.txt e fila de parsing
  • Fetcher: retirava URLs da fila por domínio e fazia o fetch; com asyncio, executava de 6000 a 7000 tarefas simultâneas, tendo a CPU como principal gargalo
  • Parser: 80 workers assíncronos, responsáveis por parsing de HTML e extração de links, com carga centrada em CPU
  • Armazenamento: em vez de S3, foi escolhido o armazenamento local da instância, reduzindo o custo de guardar páginas grandes
  • Sharding: os domínios eram distribuídos entre os nós (sem comunicação cruzada), e a quantidade de nós de sharding foi ajustada para resolver o desequilíbrio causado por domínios populares

Principais alternativas e experimentos

  • Foram testados vários armazenamentos, como SQLite e PostgreSQL, e no fim o Redis apresentou o melhor desempenho
  • Também foi tentado escalonamento vertical (uma única instância grande), mas surgiram gargalos por limitações de software; por isso, a decisão final foi por escalonamento horizontal (vários nós)
  • Foi eliminada a comunicação cruzada entre nós, mantendo o paralelismo dentro de cada nó

Principais lições durante o crawling

Parsing é o maior gargalo

  • O tamanho médio das páginas ficou muito maior do que no passado (2012: 51KB), chegando a 242KB em média e 138KB de mediana
  • Ao trocar lxml por selectolax (baseado em Lexbor), a velocidade de parsing aumentou bastante
  • A truncagem do tamanho máximo da página para 250KB melhorou a eficiência
  • Como resultado, um único parser alcançou 160 páginas por segundo; ao final, a proporção fetcher:parser foi ajustada para 9:6, processando cerca de 950 páginas por segundo

Fetching: o que ficou mais fácil e o que ficou mais difícil

  • A largura de banda da rede não foi, na prática, o gargalo (por nó, usava apenas cerca de 8Gbps dos 25Gbps disponíveis)
  • O gargalo de DNS também não foi um problema, já que o alvo eram apenas domínios populares
  • Em contrapartida, o handshake SSL apareceu como um dos maiores gargalos, consumindo 25% do uso total de CPU
  • Como a maioria das páginas migrou para HTTPS, o custo de CPU aumentou

Execução real do crawl e problemas

  • Nos experimentos iniciais, o processo rodou por algumas horas em um único nó (i7i.2xlarge), e depois o crawl principal foi ampliado para 12 nós
  • Surgiram problemas de memória: o frontier de domínios populares (URLs ainda não visitadas) crescia para dezenas de GB, derrubando os nós repetidamente
  • Domínios populares (como yahoo.com e wikipedia.org) ou sites com quantidade anormal de links causavam os problemas
  • Os domínios problemáticos foram excluídos manualmente e, quando ocorria falha, a recuperação era feita com reinicialização do nó e truncagem do frontier

Comparação entre teoria e prática

  • Em comparação com a estimativa clássica de "10 bilhões de páginas em 5 dias com 5 máquinas", os números reais ficaram relativamente próximos
  • Considerando o uso real de rede e CPU em cada nó, seria possível obter throughput ainda maior dependendo do nível de otimização

Próximos desafios e reflexões

  • Reconfirmou-se que mesmo só com parsing de HTML ainda é possível acessar uma parcela significativa da web; porém, em grandes plataformas (como GitHub), o conteúdo principal relevante fica dentro de JS e não pode ser parseado
  • Como tarefa futura, será necessário explorar custos e métodos de crawling em larga escala baseado em renderização de JS
  • A análise dos dados (metadados das páginas realmente coletadas, proporção de páginas ativas/inativas etc.) também foi mencionada como tema posterior
  • Mais recentemente, tem aumentado o crawling agressivo combinado com IA, e o ambiente de web crawling volta a mudar com o surgimento de novos sistemas de defesa, como o pay-per-crawl da Cloudflare

3 comentários

 
oninepa 2025-07-28

Impressionante mesmo..palmas palmas palmas...

 
tensun 2025-07-23

Interessante. Foi muito bom ler, obrigado.

 
yangeok 2025-07-23

Impressionante.. é uma luta entre a lança e o escudo? haha