Slide 1

Slide 1 text

Step Functions Expressで作る フルマネージドなサーバーレスバッチ 遠藤 大輔

Slide 2

Slide 2 text

はじめに • コメント待ちしております! • jawsdays2021 • jawsug • jawsdays2021_C

Slide 3

Slide 3 text

遠藤 大輔 Daisuke Endo 株式会社ゆめみ • 2019年, 株式会社ゆめみに入社 • 趣味はドラム, コンガ演奏 • Twitter: @DddEndow 好きなAWSのサービス:Step Functions

Slide 4

Slide 4 text

よくあるバッチ処理の めんどくささ

Slide 5

Slide 5 text

外部API バッチ サーバー ユーザーデータ 取得

Slide 6

Slide 6 text

外部API バッチ サーバー ユーザーデータ 取得 5〜10分毎 処理時間:数分 実装も簡単

Slide 7

Slide 7 text

外部API バッチ サーバー ユーザーデータ 取得 5〜10分毎 処理時間:数分 実装も簡単 l サーバー l ミドルウェア l フレームワーク わざわざ用意するのめんどう →サクッと作りたい!

Slide 8

Slide 8 text

AWS Lambdaなら 全部解決する?

Slide 9

Slide 9 text

AWS Lambda 処理が複雑になると… • コードがスパゲッティ化 • 責務が大きくなりすぎる • 並列処理が辛い

Slide 10

Slide 10 text

そこで AWS Step Functions

Slide 11

Slide 11 text

AWS Step Functions • サーバーレスな関数オーケストレーター • イベント駆動型のワークフローを構築 • 並列処理, 例外処理, 再試行ロジックなどを管理可能 • Lambdaなど他のサービスと組み合わせ可能

Slide 12

Slide 12 text

並列処理 例外処理 条件分岐

Slide 13

Slide 13 text

でも、あまり現実的なアーキテクチャではなかった • 料金 • DBコネクション問題 • Lambdaのコールドスタート

Slide 14

Slide 14 text

それが

Slide 15

Slide 15 text

料金(2019/12) →Step Functions Express Workflows DBコネクション問題(2020/7) →RDS Proxy Lambdaのコールドスタート(2019/9) →1分から1秒に改善

Slide 16

Slide 16 text

AWSがサーバーレスバッチを 作れと言っている!!

Slide 17

Slide 17 text

というわけで

Slide 18

Slide 18 text

作りました

Slide 19

Slide 19 text

• 数万ユーザーの処理が30秒で完了 ユーザー毎に外部API実行 + DBに書き込み • コストも1万円/月以下 (Step Functions, Lambda)

Slide 20

Slide 20 text

(もう全部サーバーレスバッチでいいんじゃない?)

Slide 21

Slide 21 text

でも大変なことや辛いこともたくさんあった

Slide 22

Slide 22 text

でも大変なことや辛いこともたくさんあった 今回のメインコンテンツ

Slide 23

Slide 23 text

アジェンダ • 並列処理 • データベース接続 • CI/CD • ログ・X-Ray

Slide 24

Slide 24 text

並列処理

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Step Functions

Slide 27

Slide 27 text

①対象ユーザーを一覧取得 ②外部APIへリクエスト ③データ処理&保存

Slide 28

Slide 28 text

①対象ユーザーを一覧取得 ②外部APIへリクエスト ③データ処理&保存 ユーザー単位で 並列処理

Slide 29

Slide 29 text

Mapステート • Step Functionsの状態の一つ • タスク単位で並列処理が可能 • パラメータ一個で同時実行数を制御可能 • キューやイベントの管理不要 並列処理 Mapステート

Slide 30

Slide 30 text

ユーザー単位で 並列処理

Slide 31

Slide 31 text

なんか二重になってない?

Slide 32

Slide 32 text

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-map-state.html Mapステートの同時実行数 • 並列数の上限は無限 • 同時実行数は約40が上限 • →多重にすることで(たぶん)対策

Slide 33

Slide 33 text

これで一安心! X-Rayで性能を確認してみよう!

Slide 34

Slide 34 text

これで一安心! X-Rayで性能を確認してみよう! →LambdaのPendingが大量に…

Slide 35

Slide 35 text

Lambdaのクォータ • リクエスト数/秒の制限 • 同時実行数の10倍 • 一万ぐらいまではすぐにあげてくれる • それ以上は実績やデータが必要 • GetFunction APIのリクエスト制限 • 100リクエスト/秒 • コールドスタートの際に実行 • デプロイパッケージの取得などに利用

Slide 36

Slide 36 text

Lambdaのクォータ • Mapの並列数を200ぐらいにしたらスムーズに • 急ぎでないなら40ぐらいでいいかも • Mapを多重にする意味あまりないんじゃ

Slide 37

Slide 37 text

まるっとうまく動くようになった!

Slide 38

Slide 38 text

まるっとうまく動くようになった! →ユーザー数増やしたらStep Functionsから エラー出るようになった…

Slide 39

Slide 39 text

Step Functionsのデータサイズ制限 • タスク, ステート, 入出力のデータサイズ • 約260KBの制限 • Mapステートの前後で制限オーバー • Map全体で受け渡すデータ量で計算 • 300B/ユーザー x 1000人 = 300KB

Slide 40

Slide 40 text

Step Functionsのデータサイズ制限 • S3に一時保存することで回避 • 各ユーザーのKey(ID)だけ渡す • S3が強い読み込み整合性をサポート • 上書きPUT, DELETEしても即座に反映 • 不要なパラメータはMapの最後に削除 ユーザーIDの配列 必要なデータのみ渡す ユーザーデータ

Slide 41

Slide 41 text

S3 APIの実行コスト削減と差分対策 • Lambda実行のたびにS3から取得すると高コスト • ハンドラー外で取得 しかし…

Slide 42

Slide 42 text

古いデータを参照してしまう問題 • 10分間隔であればLambdaの実行基盤がリセットされ ると予想 →実際には稀に実行基盤が残っていて古いデータを参照 • ハンドラー外にしたのが裏目に • 実行基盤がリセットされるタイミングは制御できない • S3のオブジェクトのMetadataにバージョン情報を追加 してチェックすることで対策

Slide 43

Slide 43 text

データベース接続

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

RDS Proxy • DBコネクションのプーリング&共有が可能 • Lambdaがコネクションを使い潰す問題を解決 • IAM接続とID/Pass接続の二種類

Slide 46

Slide 46 text

コネクション数の節約 • Lambdaハンドラー外でDBコネクションを生成 • コネクションが切断した場合にLambdaの実行基盤を終了 するエラーハンドリングが必要 • RDS Proxy • 数百->数十程度に圧縮可能 両方を組み合わせることで 数千→数十コネクションまで節約

Slide 47

Slide 47 text

書き込み処理をまとめる • 1ユーザー毎に書き込み処理を行うのはNG • Kinesisで100人ずつにまとめてバルクアップデート • Step FunctionsやX-Rayで追跡できなくなるのが欠点

Slide 48

Slide 48 text

CI/CD

Slide 49

Slide 49 text

CodePipeline GitHub pull sam build sam package Template file Stack Stack Stack CloudFormation

Slide 50

Slide 50 text

Stackを分割するメリット • 複数のグループ毎にリソースを展開できる • パラメータを書き換えるだけ • エンタープライズコネクションなどで効果を発揮 • 物理的・論理的にセキュア • ログやメトリクスの管理がしやすい • どのリソースで障害が発生したかがすぐにわかる

Slide 51

Slide 51 text

テンプレートを使い回す ことでこんなことも

Slide 52

Slide 52 text

Stackを分割するデメリット • リソースが大量に生成される • Step Functions用のLambdaダッシュボードがなかった ら心が折れてた

Slide 53

Slide 53 text

ログ・X-Ray

Slide 54

Slide 54 text

ログ • Step Functionsの実行ログを収集可能 • Step Functions独自のステータスで出力 • ちょっとクセがある • エラーの内容にLambdaやStateの情報が含まれない • デバッグが大変 • (アップデート待ってます)

Slide 55

Slide 55 text

X-Ray • Step Functionsに対応(2020/9) • ワークフロー全体を監視可能 • 並列処理も時系列で見れる

Slide 56

Slide 56 text

まとめ

Slide 57

Slide 57 text

まとめ • 並列処理 • データベース接続 • CI/CD • ログ・X-Ray

Slide 58

Slide 58 text

サーバーレスバッチという選択肢 • 開発に集中できる • リソースやミドルウェアを気にする必要が(あまり)ない • 高性能 • サーバーレスだからこそできる設計 • 低コスト • 必要な時に必要なだけ

Slide 59

Slide 59 text

リソースに縛られないバッチシステム →より効率良く価値を提供

Slide 60

Slide 60 text

宣伝 AWS Summitに登壇します セッションタイトル 「サーバー立てっぱなしはもったいない! サーバーレスのみで構築する 中頻度&短時間バッチ」

Slide 61

Slide 61 text

Thank you for watching! YUMEMI.inc, Daisuke Endo Twitter: @DddEndow