【AWS Lambda(SAM)でつくるクローラー】Crawler Night 2020 Winter

【AWS Lambda(SAM)でつくるクローラー】Crawler Night 2020 Winter

Lambda(SAM) x Layer でリアルタイムクローリングした知見を発表してきました。

#crawler_night

391a53ae955fd9dd7d3f578756ddb29c?s=128

Hironori Tanaka

December 03, 2019
Tweet

Transcript

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

  2. ⾃⼰紹介 2 2012年〜2016年 ヤフー アドテクのインフラエンジニアや社内システムの開 発・保守を主に担当。 その他に、新卒研修のメンター・次世代リーダー育成 Yahoo!アカデミアにも参加をし、育成⼒とリーダーシ ップ⼒を向上させる。 2013年頃から副業も⾏い、AWSや開発などの技術サ

    ポートを初めて経験。 2016年〜 空 ホテル向け料⾦設定サービス「MagicPrice」の⽴ち上 げ期からエンジニアとして携り、2016年6⽉取締役兼 エンジニアとして参画。現在はプロダクト責任者 (Chief Production Officer)。
  3. 会社紹介 3

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

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

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

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

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

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

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

    ・・・ 掲載 状況 掲載 プラン 掲載 金額 ・・・ クローリング
  11. Components Frontend クローリング結果 Backend 顧客データDB クローリング結果 DB Proxy Crawler Batch

    クロール対象の⼀部 ログ保存 集計結果保存 MagicPrice 共通基盤 Machine Learning データ基盤 予約サイト イベント 予約台帳・料⾦更新連携 サイトコントローラ PMS Batch 11
  12. リアルタイムクローリングに Lambda(SAM)を選択 12

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

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

    即時にデータ取得を行うパターン 14
  15. クローリング︓取得タイミング 15 ⼀定 vs. 不明 バッチ リアルタイム

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

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

    即時にデータ取得を行うパターン 17 制約が強いところを解決したい︕
  18. ぼんやりイメージしていたこと • 取得タイミング不明の解消・取得速度 ◦ キューやAPIなどをフックにイベントを受け付ける ◦ 起動を早める。AutoScalingでは起動に時間がかかる ◦ EC2などサーバの常時稼働はコストが嵩む。サーバレス?Lambda? •

    ローカルからリリース ◦ CloudFormation?serverless framework? • ローカルで本番とほぼ同⼀環境構築 18
  19. 【個⼈的に】インフラの前提として、気にしていること • ローコストで本番稼働できる ◦ 一度開発したら、なかなか修正できないから設計段階で考える • ローカルで単体テスト + 周辺の結合テストまで実⾏できる ◦

    クラウド環境でできるだけ動かさない ◦ 周辺の結合テストはできる限り • 可能な限りデフォルトを利⽤する ◦ あれこれライブラリ入れない ◦ 小難しいことしない 19
  20. クローリングに選択した構成 20 AWS Lambda Amazon S3 Amazon SQS queue クロール対象サイト

    1. ホテル単位など分割して、 SQSにキューを貯める 2. キューをフックにLambdaを 起動させ、クローリングする 3. 2と同時にスクレイピングし、 S3にデータを保存する
  21. ローカル開発︓SAM(サーバーレスアプリケーションモデル) 21

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

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

  24. 実⾏環境 • ランタイム︓Ruby 2.5 • ライブラリ ◦ nokogiri:HTMLやXML、SAXのパーサー。XPath または CSS

    セレクタを利用して要素抽出 ◦ robotex:robot.txt からクローラーの判定可否 ◦ aws-sdk-xxxxx(AWSは個別のサービス):AWSのサービスを操作 24
  25. 実⾏してみよう 25 • sam local invoke で簡単に実⾏できる。

  26. ライブラリは、Layer 使おう(1) 26 • インストールしたライブラリのパス追加や イメージビルドなどしなくても、 デフォルトでパス追加されている • 別のLambda関数で利⽤したい場合、 共通で扱うこともできます。

    ⾃作したライブラリの共通化もできる • バイナリやスクリプトも配置できる 例.クローリングでは、HeadlessChromeで遷 移していきたいケースがある (参考︓https://github.com/hirontan/sam- template/tree/master/scraping_using_headless_c hrome_from_lambda) CloudFormation
  27. ライブラリは、Layer 使おう(2) 27 • ライブラリの配置先は決まっている(/opt 配下に)

  28. ⼀つだけ、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
  29. イベント︓⾮同期的に呼び出す(1) 29 • リアルタイムに実⾏できる • S3 / SQS / CloudWatch

    Events など 扱えるイベントはデフォルトで備わっている • ローカルでは、jsonファイルで擬似的に実⾏できる sam local generate-event でイベント作成 • 本番環境では、プロパティに Events を書いて、 デプロイする。CloudFormationの yaml ファイル に記述するだけ CloudFormation
  30. イベント︓⾮同期的に呼び出す(2) 30 • キューの受け取りは event[ʻRecordsʼ] 簡単に受け取れる • ⼀度にキューを複数受け取り できる設定も、SQS・Kinesis などでも、

    プロパティに BatchSize と記述すると 設定できる ソースコード
  31. 同時実⾏数 31 • クローリング対象サイトにダメージを与えない ように同時アクセス数は気にしなければいけない。 そのコントロールとして、同時実⾏数の制御を⾏う (もちろんソースコード内でもスリープも考える) • プロパティ ReservedConcurrentExecutions

    で 同時実⾏の予約数を制御することを忘れない • もしRDSも接続するなら、データベースへの 同時接続数制御にも。 情報があまり変わらないのであれば、 DataPipelineなどでデータベースのテーブルを CSV化して、CSVにアクセスする⽅法もあります。 CloudFormation
  32. コスト⾯での注意(CloudWatch PutLogEvents) 32 • S3 / SQS / CloudWatch Events

    / Lambda など、⼀つ⼀つは、正直積み重ならない。 しかし、無闇にログをCloudWatchに履き続けると PutLogEventsが発⽣し、料⾦が嵩む。 正常系はログに出さないなど、障害に備えられるログ出しにしてください
  33. 時間あったら本当に実⾏してみる︕ 33 https://github.com/hirontan/sam- template/tree/master/scraping_fr om_lambda

  34. わかったこと・まとめ • Lambda(SAM) x Layer でクローリングできる • リアルタイムな実⾏に適してそう(実⾏した分だけなので安価なことから) • CloudFormation・AWSサービスを理解していれば、

    組み合わせだけで簡単に仕組みが作れる • CloudWatch PutLogEventsは気を付けろ︕ 34
  35. 35

  36. 参考⽂献 • 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