58 ポイント 投稿者 GN⁺ 2025-07-23 | 3件のコメント | WhatsAppで共有
  • 10億ページ24時間でクロールした実体験と、現代的なWebクローリングシステム設計の過程を共有
  • 最新のハードウェアとクラウド基盤により、数百ドル規模のコストで大規模クローリングを実現し、主なボトルネックがパース処理であることを確認
  • JavaScriptは実行せず、HTMLパースのみを行ったが、それでも相当数のWebページにアクセス可能だった
  • Redisベースのノードクラスタアーキテクチャを設計し、ドメイン単位のシャーディングとプロセス構成の最適化で効率を最大化
  • ネットワークよりもCPU・SSL・メモリが主要なボトルネックとして表れ、大規模ドメインのフロンティア管理が重要な課題だった

問題定義

  • 24時間以内に10億ページをクロールするという目標を設定
  • 予算は数百ドル(最終的に約462ドル)で、2012年の事例と同程度に合わせた
  • HTMLのみを収集し、JavaScriptは実行せず <a> リンクだけを抽出
  • **Politeness(礼儀あるクロール)**を重視し、robots.txtの順守、User Agent情報の明記、要請時のドメイン除外、人気上位100万ドメインのみを対象、同一ドメインに70秒待機などを適用
  • 耐障害性を確保し、ノード障害時の再起動や一部データ消失を織り込み済みとするサンプルベースのアプローチを採用

アーキテクチャと設計

  • **従来のシステム設計面接スタイル(機能ごとに分散)**とは異なり、各ノードがすべての機能(クロール状態、パース、フェッチ、保存など)を自前で処理する構成を選択
  • 12ノードを使用し、各ノードは i7i.4xlarge(16 vCPU、128GB RAM、10Gbps、3750GBストレージ)インスタンスを採用
  • 各ノードは1つのRedis9つのfetcher6つのparserプロセスで構成
  • Redisにはドメイン別フロンティア、fetch queue、訪問済みURL、Bloom filter、robots.txt、パースキューなどを保存
  • Fetcher: ドメインごとにキューから取り出してURLをフェッチし、asyncioで6000〜7000の同時処理を実行、主なボトルネックはCPU
  • Parser: 80個のasyncワーカーでHTMLをパースしリンクを抽出、CPU中心の処理
  • ストレージ: S3ではなくインスタンスのローカルストレージを選び、大容量ページ保存コストを削減
  • シャーディング: ドメイン単位でノードに分配し(クロスコミュニケーションなし)、人気ドメインの偏りを解消するためシャード数を調整

主な代替案と実験

  • SQLite、PostgreSQLなどさまざまなストレージを試し、最終的にRedisが最も高性能だった
  • 垂直スケーリング(単一の大型インスタンス)も試したが、ソフトウェア上の限界でボトルネックが発生し、最終的に水平スケーリング(複数ノード)構成を採用
  • ノード間のクロスコミュニケーションをなくし、単一ノード内で並列処理する方式にした

クローリング過程での主な教訓

パースが最大のボトルネック

  • 平均ページサイズは過去(2012年の51KB)より大幅に増加し、平均242KB、中央値138KBになっていた
  • lxml から selectolax(Lexborベース) に変更すると、パース速度が大幅に向上
  • ページ最大サイズを250KBに切り詰めることで効率を改善
  • 結果として、単一parserで毎秒160ページのパースを達成し、最終的にfetcher:parser比率を9:6に調整して約950ページ/秒を処理

Fetching: 容易になった点と難しくなった点

  • ネットワーク帯域はむしろボトルネックではなかった(ノードあたり25Gbps中、およそ8Gbpsしか使用していない)
  • DNSのボトルネックも、人気ドメインのみを対象にしたため問題にならなかった
  • 一方で、SSLハンドシェイクがCPU使用量全体の25%を占め、最大級のボトルネックの一つになった
  • ページの大半がHTTPSへ移行したことで、CPUコストが増加した

実運用でのクロール実行と問題点

  • 初期実験では単一ノード(i7i.2xlarge)で数時間だけ試し、本番クロールでは12ノードに拡張
  • メモリ問題が発生し、人気ドメインのフロンティア(未訪問URL)が数十GBまで増えて、ノードが繰り返しダウンした
  • 人気ドメイン(例: yahoo.com、wikipedia.org)や、異常にリンク数の多いサイトが問題を引き起こした
  • 問題のあるドメインは手動で除外し、障害発生時はノード再起動とフロンティアの切り詰めで復旧

理論と実践の比較

  • 従来の教科書的手法である「5台のマシンで5日間に100億ページ」という見積もりと比較して、実測値はある程度近かった
  • 各ノードの実際のネットワークおよびCPU使用率を踏まえると、最適化次第ではさらに高いスループットも可能

今後の課題と考察

  • HTMLパースだけでも相当数のWebページにアクセス可能であることを再確認。ただし大規模プラットフォーム(例: GitHubなど)は意味のある本文がJS内に含まれており、パースできない
  • 今後の課題として、JSレンダリングベースの大規模クローリングのコストと手法の探究が必要
  • データ分析(実際に収集したページのメタ情報、アクティブ/非アクティブ比率など)も後続テーマとして挙げられている
  • 最近はAIと組み合わせた**攻撃的クローリングが増えており、Cloudflareのpay-per-crawl**のような新たな防御策も登場するなど、Webクローリング環境は再び変化している

3件のコメント

 
oninepa 2025-07-28

すごいですね..パチパチパチ...

 
tensun 2025-07-23

興味深いですね。よく読ませていただきました。ありがとうございます

 
yangeok 2025-07-23

すごいですね……。矛と盾の戦いなんでしょうか(笑)