$30 off During Our Annual Pro Sale. View details »

バッチシステムをクラウドネイティブにするために考えたこと

teru0x1
November 21, 2022
4.2k

 バッチシステムをクラウドネイティブにするために考えたこと

Cloud Native Days Tokyo 2022
Session: https://event.cloudnativedays.jp/cndt2022/talks/1518

teru0x1

November 21, 2022
Tweet

Transcript

  1. © DMM © DMM CONFIDENTIAL バッチシステムを クラウドネイティブにするために 考えたこと 小野 輝也

    Cloud Native Days Tokyo 2022
  2. © DMM 2 小野 輝也
 合同会社DMM.com SRE 2021年新卒入社 Twitter: @teru0x1

    https://cha-shu00.hatenablog.com/
  3. © DMM バッチシステムをどのように 管理していますか?

  4. © DMM 4 1. 動いているのか わからない 謎のcronが発掘 される

  5. © DMM 5 2. バッチ処理が動いたり 動かなかったりする

  6. © DMM 6 3. ユーザー問い合わせで 初めてバッチ処理のエラー に気が付く

  7. © DMM 7 4. 古いバージョンの jenkinsサーバが アップグレードされずに 放置されている

  8. © DMM 今日話すこと • クラウドネイティブ時代のバッチシステム設計時に重要な視点 • VMベースのバッチシステムをECS Fargate + Step

    Functions に移行させた事例 • 本セッションで扱う”バッチシステム” • 従来はLinuxのcronで動かしていたような比較的小規模なバッチジョブを 対象 • データサイエンス、機械学習、HPCといった領域の大規模なバッチジョブシス テムは対象外 8
  9. © DMM クラウドネイティブな バッチシステム設計時に重要な視点

  10. © DMM 10 クラウドネイティブ クラウドネイティブ技術は、パブリッククラウド、プライベートクラウド、ハイブリッドクラウドなどの近 代的でダイナミックな環境において、スケーラブルなアプリケーションを構築および実行す るための能力を組織にもたらします。 このアプローチの代表例に、コンテナ、サービスメッ シュ、マイクロサービス、イミュータブルインフラストラクチャ、および宣言型APIがあります。 これらの手法により、回復性、管理力、および可観測性のある疎結合システムが実現しま

    す。 これらを堅牢な自動化と組み合わせることで、エンジニアはインパクトのある変更を最小 限の労力で頻繁かつ予測どおりに行うことができます。 CNCF Cloud Native Definition v1.0 (2018)
  11. © DMM 11 回復性 管理性 (管理力) 可観測性 フォールト(障害を起こしうるもの)に対応して機能 を継続できる 「付加価値の産まない重労働」が少ない

    分散システム全体の状態を把握でき、異常時の アクションを可能にする
  12. © DMM 12 視点1 個々のバッチジョブを 分離したインフラ リソースとして扱えるか • ジョブごとに隔離されたコンピューティング環 境で実行可能

    ◦ 単一マシン上のcronの場合、ジョブが互いに影響を 及ぼす • ジョブごとにリソース量の調整、有効・無効設定 が容易 • ジョブごとに実行状態、実行時間が観測可能 管理性 可観測性
  13. © DMM 13 視点2 自動・手動の リトライが容易か • 自動リトライすべき例: インフラの一時的なフォール トによる起動エラー発生時のリトライ

    ◦ 必ずバッチ処理の実行前に発生するため、 安全にリトライ可能 • 手動リトライの例: バグによる処理失敗時の 再試行 回復性 管理性
  14. © DMM 14 視点3 実行ロギング・ステータスの 通知が可能か • ジョブ実行履歴のログを残せる ◦ ジョブが終わった後何も残らない場合、

    デバッグが困難になる • アプリケーションのログを外部に送信できる ◦ 古いcronではログを/dev/nullに捨てがち... • ジョブ実行のステータスを外部に通知できる ◦ 成功率・実行時間を収集できる ◦ 通知をトリガーにして、リトライなどが実行できる 可観測性
  15. © DMM 15 視点4 バッチ実行基盤の 運用効率が良いか • バッチ実行基盤として何を使うか? ◦ マネージド・サーバーレスなクラウド

    サービスを組み合わせる ▪ ほぼ管理作業が発生しない ◦ ジョブ管理システムの導入 ▪ 例: jenkins, Rundeckなど ▪ バージョンアップ作業、ユーザ管理作業 などが発生する ▪ OSSのものはコードを調査できる、 議論に参加できる • 組織によって最も効率の良いものを選ぶ 管理性
  16. © DMM 16 これらの視点は最初から持っていたわけではなく、 バッチシステムのモダン化を行った際に考慮したことから 学び、抽出したものです 以降ではそのバッチシステム移行の過程を紹介します

  17. © DMM 背景 17 ELB ELB Aurora Aurora Amazon Web

    Services、“Powered by AWS”ロゴ、[およびかかる資料で使用されるその他のAWS商標] は、米国その他の諸国における、Amazon.com Inc.またはその関連会社の商標です。
  18. © DMM 背景 18 • 弊社のとあるWebサービスの インフラ • Webサーバ(複数台)+ バッチサーバ(1台)

    + DBサーバ • オンプレ上のVM→AWS EC2へそのまま載せ替え(lift & shift)が完了していた Aurora ELB
  19. © DMM 背景 19 • システム全体をクラウドネイティブに 刷新するプロジェクトが始動 • 先行してWebサーバのインフラが ECS

    Fargateに変更 • バッチに関してはEC2を脱却するこ とで以下の課題の解決を目指した • 耐障害性がない • エラー発生を検出できない • 全てのジョブプロセスが同居す るのでリソースを奪い合う • crontabファイルの編集によ るスケジュール設定変更が常態 化 Aurora Aurora
  20. © DMM 技術選定

  21. © DMM 21 cron on ECS Service ✅ 既存のcronをそのまま利用できる ✅

    インフラの障害に対して回復性がある ❌ ジョブ同士が互いにリソースを奪い合っ てしまう ❌ 新バージョンリリース時にジョブが停止し てしまう ジョブが分離できないのが欠陥となる 視点1: 「ジョブがインフラリソースとして分離されているか」
  22. © DMM 22 ジョブ管理システム on ECS Service ✅ ジョブは互いに影響を及ぼさない(個別 のタスクとなる)

    ✅ 手動・自動リトライが可能 ✅ 実行のロギング・エラー通知が可能 ❌ ジョブ管理システム自体の運用コストがや や大きい ジョブ管理システムの構築と運用にかかる負担が大きいと判断 そこまで豊富な機能を必要としていなかった 視点4: 「バッチ実行基盤の運用効率が良いか」
  23. © DMM 23 ECS Scheduled Task + EventBridge + Kinesis

    Data Firehose ✅ ジョブは互いに影響を及ぼさない ✅ マネージドかつサーバレスな実行基盤 ✅ 構成がシンプル ✅ 実行ログをEventBridgeとFirehose 経由で保存できる(ECS単体では一定時間で 消滅してしまう) ❌ 単体での自動/手動リトライは不可能 シンプルな構成で、cron on EC2脱却の1歩目に適すると判断 自動リトライなどはこの時点では不要だと考えていた(後述) 視点3: 実行ロギング・ステータスの通知が可能か
  24. © DMM 改善実装 v1 • 個々のジョブを隔離された コンテナで実行 • ジョブごとの実行ログ取得 •

    Terraformによる実行スケジュール 管理 24 できるようになったこと しかし、新たな問題が発覚...
  25. © DMM 問題1: バッチジョブが稀に実行されない

  26. © DMM バッチジョブが稀に実行されない • ECS Fargateのタスク起動時にプロビジョニングエラーが発生 • サポートに問い合わせた結果、どうしても低確率で発生するもの • 自動的なリトライが必要

    26 • Timeout waiting for network interface provisioning to complete • ResourceInitializationError: failed to configure ENI: failed to setup regular eni: context deadline exceeded • ResourceInitializationError: failed to configure ENI: failed to setup regular eni: netplugin failed with no error message ECSタスクのStoppedReasonとしてよく見るもの 視点2: 自動・手動のリトライが容易か
  27. © DMM 問題2: EventBridgeがターゲットを複数回呼び出す

  28. © DMM EventBridgeがターゲットを複数回呼び出す • EventBridgeは稀にターゲット(ECSタスク)を複数回呼び出すことがある(docsに 記載あり) • 重複呼び出しされると不具合に繋がるジョブが少数ながら存在していた • 歴史的な背景からアプリケーションレベルでの冪等性は備わっていなかった

    • バッチシステム側で重複起動されないような仕組みが欲しい 28 Amazon EventBridge Rule 通常時 Amazon EventBridge Rule 複数回呼出時(稀)
  29. © DMM 改善実装 v2 29 Amazon EventBridge Rule AWS Lambda

    AWS Step Functions • Step Functions(SFN)を 利用し、ECSタスクを起動 • 利用するSFNの機能 ◦ ワークフローによる 自動リトライ ◦ 冪等応答 ▪ 同じ実行名に対し て2回以上起動し ない
  30. © DMM Rule Amazon EventBridge AWS Lambda 改善実装 v2 30

    AWS Step Functions RunTask: ECSタスクを同期実行 成功時はそのまま終了
  31. © DMM Rule Amazon EventBridge AWS Lambda 改善実装 v2 31

    AWS Step Functions RunTask: ECSタスクを同期実行 失敗時はParseCauseへ ParseCause: タスクの終了原因をJSON へパース ErrorChoice: 終了原因が指定した理由 にマッチする場合はRunTaskへ遷移 "Choices": [ { "Next": "RunTask", "Or": [ { "StringMatches": "Timeout waiting for network interface provisioning to complete*", "Variable": "$.ParsedCause.StoppedReason" }, { "StringMatches": "ResourceInitializationError: failed to configure ENI: failed to setup regular eni: context deadline exceeded", "Variable": "$.ParsedCause.StoppedReason" }, { "StringMatches": "ResourceInitializationError: failed to configure ENI: failed to setup regular eni: netplugin failed with no error message", "Variable": "$.ParsedCause.StoppedReason" } ] } ], … ]
  32. © DMM Rule Amazon EventBridge AWS Lambda 改善実装 v2 32

    AWS Step Functions LambdaでEventBridge によるターゲット多重起動を阻止 { “name”: “jobA-2022-11-02”, “stateMachineArn”: “xxxxx” }
  33. © DMM Rule Amazon EventBridge 改善実装 v2 33 LambdaでEventBridge によるターゲット多重起動を阻止

    1回目呼出(起動) 2回目呼出(起動しない)
  34. © DMM Step Functionsに移行して • タスク実行失敗、重複起動リスクは回避 • AWSコンソールで実行履歴が見やすい、手動によるリトライが簡単 といった副次的メリットも生まれた 34

    • 余談 • AWS Batchは検討しなかったのか? • SFNのような冪等応答の機能がない • 重複起動の件はDynamoDBなどで排他制御することでも解決できそうか? • ジョブが1分以内で完了した場合、1個目のタスク終了後に2個目のタスクが起動することがある模様... • cf. https://qiita.com/aosho235/items/87cc5f6104392f5fcdc6
  35. © DMM 35 まとめ

  36. © DMM まとめ • クラウドネイティブ時代のバッチシステム設計時に重要な視点 • 個々のバッチジョブを分離したインフラリソースとして扱えるか • 自動・手動のリトライが容易か •

    実行ロギング・ステータスの通知が可能か • バッチ実行基盤の運用効率が良いか • VMベースのバッチシステムをECS Fargate + Step Functions に移行させた事例を紹介 36
  37. © DMM We are hiring! 大規模なサービスや新事業の立ち上げなど規模の大小、ジャンル・フェーズ が存在するDMM.comでSREを実践してみませんか? https://dmm-corp.com/recruit/engineer/8/

  38. Thank You !