AWSでクローラを動かす時のアーキテクチャを考える


## はじめに
AWS上でクローラを動かしたいときがある。
様々な選択肢があると思われるが、とりあえず思い付いたアーキテクチャ（構成）を書く。
どの構成が良いとかは不明（もっと良いアーキテクチャあると思う）。良し悪しの基準の定義がめんどいからとりあえず書く。

## クローラについて
- ここでは、クローラとは「webページからデータを取得し、それを構造化するプログラム」と定義する

## クロール対象について
- 何かしらの「物」（洋服、食べ物、不動産、etc）を閲覧できるwebページ
- 「物」の一覧ページと「物」それぞれの詳細ページ、という構成である
- 「物」を検索する機能がある（場合がほとんど）

## クロールの処理について
クロールの処理は主に３つのフェーズがあると考えられる

```
    
    +------------------------------------------------------------+
    |                                                            |
    |                                                            |
    |  +-----------+        +------------+        +----------+   |   +----+
    |  |           |  url   |            |  html  |          |   |   |    |
    |  |  crawler  | +----> | downloader | +----> |  parser  | +---> | DB |
    |  |           |        |            |        |          |   |   |    |
    |  +-----------+        +------------+        +----------+   |   +----+
    |                                                            |
    |                                                            |
    +------------------------------------------------------------+
    

```

1.crawler→「物」の一覧ページを読み込み、詳細ページのURLを収集する
2.downloader→1で集めたURLを元に、詳細ページのHTMLをダウンロードする
3.parser→2でダウンロードしたHTMLから欲しい情報を抜き出す（そしてDB等に保存する）

## AWSでクローラを動かす

#### 案１：普通にEC2を使う

```
      EC2
+---------------------------+
| crawler/downloader/parser |
|      Trigger=> cron       |
+---------------------------+

```

- EC2で普通にバッチを動かす感じ


#### 案２：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できる


#### 案３：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を増やすことでスケールアウトできるが、各サイトごとの処理時間短縮にはならない