はじめに
AWS上でクローラを動かしたいときがある。
様々な選択肢があると思われるが、とりあえず思い付いたアーキテクチャ(構成)を書く。
どの構成が良いとかは不明(もっと良いアーキテクチャあると思う)。良し悪しの基準の定義がめんどいからとりあえず書く。
クローラについて
- ここでは、クローラとは「webページからデータを取得し、それを構造化するプログラム」と定義する
クロール対象について
- 何かしらの「物」(洋服、食べ物、不動産、etc)を閲覧できるwebページ
- 「物」の一覧ページと「物」それぞれの詳細ページ、という構成である
- 「物」を検索する機能がある(場合がほとんど)
クロールの処理について
クロールの処理は主に3つのフェーズがあると考えられる
+------------------------------------------------------------+
| |
| |
| +-----------+ +------------+ +----------+ | +----+
| | | url | | html | | | | |
| | crawler | +----> | downloader | +----> | parser | +---> | DB |
| | | | | | | | | |
| +-----------+ +------------+ +----------+ | +----+
| |
| |
+------------------------------------------------------------+
1.crawler→「物」の一覧ページを読み込み、詳細ページのURLを収集する
2.downloader→1で集めたURLを元に、詳細ページのHTMLをダウンロードする
3.parser→2でダウンロードしたHTMLから欲しい情報を抜き出す(そしてDB等に保存する)
AWSでクローラを動かす
案1:普通にEC2を使う
EC2
+---------------------------+
| crawler/downloader/parser |
| Trigger=> cron |
+---------------------------+
- EC2で普通にバッチを動かす感じ
案2:ElasticBeanstalkのWorkerを使う
SQS ElastiCache S3
+-----------+ +----------+ +---------------+
| | | | | |
| job queue | | lock | | shared data |
| | | | | |
+----+------+ +----+-----+ +---+-----------+
^ ^ ^
| | |
| | |
+-----------+------------------+----------------+------------+
| |
Lambda | worker1 worker2 worker3 | EC2
+---------+ | +-----------+ +------------+ +----------+ | +-----------+
| | | | | url | | html | | | | |
| Trigger | +---> | | crawler | +----> | downloader | +----> | parser | +---> | mongoDB |
| | | | | | | | | | | |
+---------+ | +-----------+ +------------+ +----------+ | +-----------+
| |
| |
+------------------------------------------------------------+
Elastic Beanstalk
- ElasticBeanstalkのworkerを使う
- workerを増やすことでスループットが上がる
- SQSに溜まったジョブの量に合わせてauto scaleできる
案3:ECS Tasksを使う
EC2 Container Service
+-----------------------------------------------------+
| |
Lambda | container1 container2 container47 |
+---------+ | +----------+ +----------+ +----------+ |
| | | | | | | | | |
| Trigger | +---> | | site_1 | | site_2 | ...... | site_n | |
| | | | | | | | | |
+---------+ | +----------+ +----------+ +----------+ |
| X |
| X |
+-------X---------------------------------------------+
X
X
+---------X-------------------------+
| |
| crawler -> downloader -> parser |
| |
+-----------------------------------+
- クロール対象サイトごとにコンテナ(ECSのTask)を立ち上げる
- シンプルで開発者の頭はすっきりする
- Container Instanceを増やすことでスケールアウトできるが、各サイトごとの処理時間短縮にはならない