Slide 1

Slide 1 text

AWS Lambda(SAM) でつくるクローラー 株式会社空 ⽥仲 紘典

Slide 2

Slide 2 text

⾃⼰紹介 2 2012年〜2016年 ヤフー アドテクのインフラエンジニアや社内システムの開 発・保守を主に担当。 その他に、新卒研修のメンター・次世代リーダー育成 Yahoo!アカデミアにも参加をし、育成⼒とリーダーシ ップ⼒を向上させる。 2013年頃から副業も⾏い、AWSや開発などの技術サ ポートを初めて経験。 2016年〜 空 ホテル向け料⾦設定サービス「MagicPrice」の⽴ち上 げ期からエンジニアとして携り、2016年6⽉取締役兼 エンジニアとして参画。現在はプロダクト責任者 (Chief Production Officer)。

Slide 3

Slide 3 text

会社紹介 3

Slide 4

Slide 4 text

4 社名︓株式会社空 代表者︓松村⼤貴 設⽴︓2015年 従業員︓30名(⾮正規社員含む) URL︓https://www.sora.flights/

Slide 5

Slide 5 text

Vision 5 ⾰新的なサービスをつくりながら、幸せな働き⽅を世界に広めます

Slide 6

Slide 6 text

6 世界中の価格を最適化し、売り⼿も買い⼿も嬉しい世界を作る Mission

Slide 7

Slide 7 text

7 「MagicPrice」ホテルの料⾦設定をとことんシンプルに Service

Slide 8

Slide 8 text

精度=料⾦設定のムラ ノウハウが属⼈化しており、担当者が変わると やり⽅が変わる。 経験とカンに頼る部分が⼤きく、 上⼿くいく⽉といかない⽉が出てしまう。 ⼿間=料⾦設定のムダ 調査や分析にかかる時間は1⽇1〜3時間。 ⽉に60時間も、経営や戦略を担う従業員の 時間を使っている。 Issues 8

Slide 9

Slide 9 text

クローリングをどこで利⽤しているのか 9

Slide 10

Slide 10 text

Research 10 予約 状況 ⾃ホテル︓⾃ホテルの予約データを連携 競合ホテル︓マーケット情報を収集 予約 プラン 予約 金額 ・・・ 掲載 状況 掲載 プラン 掲載 金額 ・・・ クローリング

Slide 11

Slide 11 text

Components Frontend クローリング結果 Backend 顧客データDB クローリング結果 DB Proxy Crawler Batch クロール対象の⼀部 ログ保存 集計結果保存 MagicPrice 共通基盤 Machine Learning データ基盤 予約サイト イベント 予約台帳・料⾦更新連携 サイトコントローラ PMS Batch 11

Slide 12

Slide 12 text

リアルタイムクローリングに Lambda(SAM)を選択 12

Slide 13

Slide 13 text

クローリング・スクレイピング 13 ウェブサイトからHTMLを取得 HTMLから任意の情報を抽出

Slide 14

Slide 14 text

クローリング︓2種類のパターン ● バッチ ○ 情報差分の更新やデータ分析に時系列情報としての取り扱いなど 特に即時性は求めないが、一定間隔でデータ取得をしておくパターン ● リアルタイム ○ ホテルで言えば、価格や在庫の情報など現在情報を知るために、 即時にデータ取得を行うパターン 14

Slide 15

Slide 15 text

クローリング︓取得タイミング 15 ⼀定 vs. 不明 バッチ リアルタイム

Slide 16

Slide 16 text

クローリング︓取得の速さ 16 求められ 「ない」 vs. 求められ 「る」 バッチ リアルタイム

Slide 17

Slide 17 text

クローリング︓わがままなリアルタイム︕ ● バッチ ○ 情報差分の更新やデータ分析に時系列情報としての取り扱いなど 特に即時性は求めないが、一定間隔でデータ取得をしておくパターン ● リアルタイム ○ ホテルで言えば、価格や在庫の情報など現在情報を知るために、 即時にデータ取得を行うパターン 17 制約が強いところを解決したい︕

Slide 18

Slide 18 text

ぼんやりイメージしていたこと ● 取得タイミング不明の解消・取得速度 ○ キューやAPIなどをフックにイベントを受け付ける ○ 起動を早める。AutoScalingでは起動に時間がかかる ○ EC2などサーバの常時稼働はコストが嵩む。サーバレス?Lambda? ● ローカルからリリース ○ CloudFormation?serverless framework? ● ローカルで本番とほぼ同⼀環境構築 18

Slide 19

Slide 19 text

【個⼈的に】インフラの前提として、気にしていること ● ローコストで本番稼働できる ○ 一度開発したら、なかなか修正できないから設計段階で考える ● ローカルで単体テスト + 周辺の結合テストまで実⾏できる ○ クラウド環境でできるだけ動かさない ○ 周辺の結合テストはできる限り ● 可能な限りデフォルトを利⽤する ○ あれこれライブラリ入れない ○ 小難しいことしない 19

Slide 20

Slide 20 text

クローリングに選択した構成 20 AWS Lambda Amazon S3 Amazon SQS queue クロール対象サイト 1. ホテル単位など分割して、 SQSにキューを貯める 2. キューをフックにLambdaを 起動させ、クローリングする 3. 2と同時にスクレイピングし、 S3にデータを保存する

Slide 21

Slide 21 text

ローカル開発︓SAM(サーバーレスアプリケーションモデル) 21

Slide 22

Slide 22 text

ローカル開発︓SAM(サーバーレスアプリケーションモデル) 22

Slide 23

Slide 23 text

Lambda(SAM)でクローリング 23

Slide 24

Slide 24 text

実⾏環境 ● ランタイム︓Ruby 2.5 ● ライブラリ ○ nokogiri:HTMLやXML、SAXのパーサー。XPath または CSS セレクタを利用して要素抽出 ○ robotex:robot.txt からクローラーの判定可否 ○ aws-sdk-xxxxx(AWSは個別のサービス):AWSのサービスを操作 24

Slide 25

Slide 25 text

実⾏してみよう 25 • sam local invoke で簡単に実⾏できる。

Slide 26

Slide 26 text

ライブラリは、Layer 使おう(1) 26 • インストールしたライブラリのパス追加や イメージビルドなどしなくても、 デフォルトでパス追加されている • 別のLambda関数で利⽤したい場合、 共通で扱うこともできます。 ⾃作したライブラリの共通化もできる • バイナリやスクリプトも配置できる 例.クローリングでは、HeadlessChromeで遷 移していきたいケースがある (参考︓https://github.com/hirontan/sam- template/tree/master/scraping_using_headless_c hrome_from_lambda) CloudFormation

Slide 27

Slide 27 text

ライブラリは、Layer 使おう(2) 27 • ライブラリの配置先は決まっている(/opt 配下に)

Slide 28

Slide 28 text

⼀つだけ、Layer のハマりポイント 28 • Rubyのバージョンが揃っていないとライブラリの読み込みされない可能性がある。 • イメージ「 lambci/lambda:build-ruby2.5 」を利⽤して、ビルドした結果をローカルに配置 し直した結果を利⽤する • スクリプト⽤意しているので参考にしてください layers/ ├── builds │ └── build_ruby-serverless-crawling-gems.sh ├── docker │ └── Dockerfile_ruby-serverless-crawling-gems └── gemfiles ├── Gemfile_ruby-serverless-crawling-gems └── Gemfile_ruby-serverless-crawling-gems.lock https://github.com/hirontan/sam-template/tree/master/scraping_from_lambda/layers

Slide 29

Slide 29 text

イベント︓⾮同期的に呼び出す(1) 29 • リアルタイムに実⾏できる • S3 / SQS / CloudWatch Events など 扱えるイベントはデフォルトで備わっている • ローカルでは、jsonファイルで擬似的に実⾏できる sam local generate-event でイベント作成 • 本番環境では、プロパティに Events を書いて、 デプロイする。CloudFormationの yaml ファイル に記述するだけ CloudFormation

Slide 30

Slide 30 text

イベント︓⾮同期的に呼び出す(2) 30 • キューの受け取りは event[ʻRecordsʼ] 簡単に受け取れる • ⼀度にキューを複数受け取り できる設定も、SQS・Kinesis などでも、 プロパティに BatchSize と記述すると 設定できる ソースコード

Slide 31

Slide 31 text

同時実⾏数 31 • クローリング対象サイトにダメージを与えない ように同時アクセス数は気にしなければいけない。 そのコントロールとして、同時実⾏数の制御を⾏う (もちろんソースコード内でもスリープも考える) • プロパティ ReservedConcurrentExecutions で 同時実⾏の予約数を制御することを忘れない • もしRDSも接続するなら、データベースへの 同時接続数制御にも。 情報があまり変わらないのであれば、 DataPipelineなどでデータベースのテーブルを CSV化して、CSVにアクセスする⽅法もあります。 CloudFormation

Slide 32

Slide 32 text

コスト⾯での注意(CloudWatch PutLogEvents) 32 • S3 / SQS / CloudWatch Events / Lambda など、⼀つ⼀つは、正直積み重ならない。 しかし、無闇にログをCloudWatchに履き続けると PutLogEventsが発⽣し、料⾦が嵩む。 正常系はログに出さないなど、障害に備えられるログ出しにしてください

Slide 33

Slide 33 text

時間あったら本当に実⾏してみる︕ 33 https://github.com/hirontan/sam- template/tree/master/scraping_fr om_lambda

Slide 34

Slide 34 text

わかったこと・まとめ ● Lambda(SAM) x Layer でクローリングできる ● リアルタイムな実⾏に適してそう(実⾏した分だけなので安価なことから) ● CloudFormation・AWSサービスを理解していれば、 組み合わせだけで簡単に仕組みが作れる ● CloudWatch PutLogEventsは気を付けろ︕ 34

Slide 35

Slide 35 text

35

Slide 36

Slide 36 text

参考⽂献 ● AWS サーバーレスアプリケーションモデル https://aws.amazon.com/jp/serverless/sam/ ● AWS Lambda レイヤー https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration- layers.html ● AWS CloudFormation https://aws.amazon.com/jp/cloudformation/ ● AWS::Lambda::EventSourceMapping https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/User Guide/aws-resource-lambda-eventsourcemapping.html 36