AWS Batch とは何か

AWS re:Invent 2016 で発表された AWS Batch。
語感から、誤解されるサービス No.1 な気がします。
定時バッチなどとは何がどう違うのかをメモ。


# 機能概要

以下公式資料とドキュメント、実際さわってみた所感を合わせて。

- [AWS Batch – 簡単に使えて効率的なバッチコンピューティング機能 – AWS](https://aws.amazon.com/jp/batch/)
- [AWS Black Belt Online Seminar「AWS Batch」の資料およびQA公開](http://aws.typepad.com/sajp/2017/02/aws-black-belt-online-seminar-aws-batch.html#QCPzBdn.twitter_tweet_count_m)

## 結局何なのか

科学技術計算・ハイパフォーマンスコンピューティング用途で真価を発揮する、
大規模なスケール、**ジョブの依存定義** が可能なマネージド **並列分散** 処理基盤。

## 主な機能、ポイント

- クラスタ管理、ジョブキュー、ジョブスケジューラを AWS にお任せできる
- 処理すべきジョブの数に応じ、適切に **自動伸縮**[^1] するクラスタ
- ジョブに **依存関係** が定義できる（B は A に依存した処理である[^2]、など）
- **優先度** を持ったキューを複数定義できる
- 処理能力ごとにクラスタを分割管理することもできる
- リソース調達が EC2 より直感的、かつ Spot Fleet も統合済み
- クラスタは ECS 上に構築される
- サードパーティのデータ分析ワークフローエンジンのサポートあり

[^1]: Managed 環境だった場合の挙動
[^2]: A が正常終了（`SUCCEEDED`）すると B が開始され、A が異常終了（`FAILED`）した場合は B も `FAILED` になる

## これがマネージドされると僕らは何がうれしいのか

- 本来やりたい、ジョブの実行依頼（submit）と実処理だけを考えればよくなる
- クラスタ全体で利用可能なリソースの把握、過不足に応じたその調整が不要[^3]に
- 前処理、集約処理、後処理といった**流れのある処理**も基盤側に制御を移譲できる
- **依頼者や状況に応じた**優先的リソース配分が容易に実現できる
- CPU / GPU でそれぞれクラスタを作り、前処理 CPU、本処理 GPU なども簡単
- クラスタごとに可用性、パフォーマンス、コストのバランスが定義しやすい
- Docker イメージにさえしてしまえばどんな処理も AWS Batch に乗せられる
- すでにデータ分析パイプラインの定義があれば移行しやすい（かもしれない）

[^3]: 厳密には待機ジョブの数で調整がかかるので、CPU やメモリなどに応じたリソースの調達・解放がしたい場合は API を利用したプログラムが別途必要

## 逆に現在[^4]サポートしていないこと

以下 API を駆使してプログラムは書けるものの、標準機能にはありません。

- cron のように事前指定した時間での起動など、定期タスク管理
- ジョブの処理そのものや待機状態のタイムアウト
- 処理が失敗した場合のリトライ
- リソース不足時、どのリソースがどれだけ足りないかの把握

[^4]: 2017/03/01 時点

## 定時バッチのマネージドサービスではないよという話

再掲:「AWS Black Belt Online Seminar 2017 AWS Batch」10 ページ目
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-aws-batch/10

ストリーミングではなく、（本来の意味の）バッチ的に渡ってくるタスクを
スケーラブルに並列処理させるための仕組みとのことです。

# ユースケース

## 公式

以下からも明らかに主なターゲットはシミュレーションやデータ解析のための処理。
**変数を変えながら大量に流す処理** や **細切れにして並列に流せる処理** が向いている。

- [金融サービス](https://aws.amazon.com/jp/batch/use-cases/#financial-services)
    - ハイパフォーマンスコンピューティング
    - ポストトレード解析
    - 不正調査
- [ライフサイエンス](https://aws.amazon.com/jp/batch/use-cases/#life-sciences)
    - 薬剤スクリーニング
    - DNA シーケンシング
- [デジタルメディア](https://aws.amazon.com/jp/batch/use-cases/#digital-media)
    - レンダリング
    - トランスコーディング
    - メディアサプライチェーン

## 公式（番外編）

膨大なパラメタを探索したり、予め大量の画像に推論したラベルを貼るといった
昨今話題となっている深層学習分野にも有用、今後利用は広がりそう。

- [Classify a Large Number of Images with Amazon Rekognition and AWS Batch](https://aws.amazon.com/jp/blogs/ai/classify-a-large-number-of-images-with-amazon-rekognition-and-aws-batch/)

## 個人的印象

上の深層学習の例では API 消費にレートリミットをかけるという位置付けで
AWS Batch を使っていますが、この使い方はとても汎用的だと思います。
ということで、以下あたりも向いていそう。

- レートリミットをかけたい処理の実行

例えば同時に流してよい処理がクラスタ全体で一つだけであるとか、
3 つ程度にしたいといった時にクラスタとジョブの定義だけで調整可能。

- ECS で RunTask していた非同期タスク

科学技術計算といった高度なものではなく、もっとシンプルなタスク。
Web / スマホアプリでも定期的に必要になる小さなジョブなども
予め Docker イメージになっているようであればすぐ使えて便利。


# リソースの管理とジョブのスケジューリング

業界によって意味の異なる言葉の整理。

HPC 界隈、コンテナ（Web）界隈、業務システム界隈それぞれで
少しずつ意味が異なるようなので、比較しながら併記します。
（AWS Batch での意味 = HPC 分野での意味）

## クラスタ、リソース管理

AWS Batch のいうクラスタは、将来的には HPC 方向に機能強化されるはず・・

- **HPC**: 施設・研究者で共有される **巨大なリソース** をクラスタとして管理。  
ジョブの要求するハードウェア性能は一般にとてもシビアであり、  
どこでどんな性能のノードが使えるかといった情報の収集も厳密。
- **コンテナ**: 複数のサービスでシェアされる特定サーバ群のことで  
一般には可用性やスケーラビリティが重視された構成が取られる。  
どのホストで稼働するかは重要ではなく、むしろどこでも動くよう設計される。
- **業務**: データセンタ内のリソースを管理。あまり包括的には扱われない。  
稼働するアプリケーションは頻繁に変わるものではなく  
とにかく安定的・効率的にサービスが稼働することが大切。

## スケジューラ

- **HPC**: 実行したいジョブはキューに投げる。リソースが空いたら次の処理が始まる。  
ジョブ同士の依存関係が強い。順序や処理間のデータ移動も重要。  
優先的に処理したいジョブは割り込める必要がある。  
多くは試行錯誤のためのジョブ、FAIL してもいいが処理時間はとにかく長い。
- **コンテナ**: 各サービスの要求するリソースを見つけ次第どこかに投入される。  
サービスの理想状態を別途管理する必要があり、異常終了時などの再起動や  
すでに起動しているサービスの状態を考慮した配置も必要になる。
- **業務**: 業務やその時間、ワークフローに応じてジョブを起動・停止する。  
ジョブ同士の依存関係も強く、処理に失敗した場合のワークフローは最も複雑。  
ユーザごとにそのあたりを設定変更できる柔軟さが必要。


# AWS Batch の概念・機能

## コンピューティング環境

AWS Batch には「コンピューティング環境」という概念がありますが
いわゆる「クラスタ」のようなもので、複数インスタンスの集合です。

そしてそれは、用途に応じて 2 種類あります。

### Managed 環境

Unmanaged でなければいけない理由がなければ Managed 環境がオススメ。
Managed 環境の特徴は以下の通り。

- 待機ジョブの深さに応じてクラスタがオートスケールアウト / イン
- ECS クラスタを裏で作成・管理してくれる
- Spot Fleet が簡単に使えて便利

### Unmanaged 環境

ちょっと変わったクラスタにカスタマイズする必要がある場合はこちら。
AWS Batch の生成する ECS クラスタに「関連づけるインスタンス」を
自由にカスタマイズ可能。例えばこんなとき。

- 特定の AMI を使いたい
- あれこれ調整した AutoScaling グループを使いたい
- EFS を使いたい
- GPU を使いたい

Unmanaged 環境の場合はキューの深さによるオートスケールが働かないため
[このようなアーキテクチャ](https://www.slideshare.net/AmazonWebServices/announcing-aws-batch-run-batch-jobs-at-scale-december-2016-monthly-webinar-series/35) で別途用意する必要があります。

## ジョブ定義・実行

ジョブの定義は [JSON で事前に宣言](http://docs.aws.amazon.com/ja_jp/batch/latest/userguide/job_definitions.html) することになります。
ジョブの処理ロジックについては、さらにそれ以前に Docker イメージにして
DockerHub や [ECR](https://aws.amazon.com/jp/ecr/) などに push しておく必要があります。

### 実行時パラメタ

ジョブの基本的な起動パラメタは事前に JSON に定義するものの、
実行時に挙動を変える手段が AWS Batch には [2 つのあります](http://qiita.com/pottava/items/4151fcb9b14c51f50e9c)。

- **Ref:XXX** & **--parameters** : 事前に XXX と定義したパラメタを実行時に指定
- **環境変数** : コンテナへ渡す環境変数を実行時に指定

### 依存関係のあるジョブ

ジョブ投入時に `--depends-on` オプションで、すでに投入済みの
依存するジョブの ID を渡すことで依存関係を定義できます。

### ジョブ間のデータ連携

HPC 系バッチコンピューティングを支援するマネージドサービスということで
そのデータの連携には以下サービス群の利用が想定されているようです。

- **EFS**: まだ東京リージョンに来てないけども・・
- **EBS**: 前処理したタイミングでスナップショットを取り展開、など
- **S3**: AWS といえば S3 の活用ですが、もちろん大活躍
- RDS / DynamoDB: 使いどころはたくさんありそう

## 他サービスとの連携

AWS を使い倒せば、よりセキュアで安定したサービスにも

- **CloudWatch Logs**: ジョブの標準出力は全てここに連携されます
- **IAM**: ECS ベースなこともあり、ジョブごとの権限管理にはロールが使える
- **KMS**: 秘密情報の管理には KMS + IAM ロールがほんとに便利
- Lambda + CloudWatch Events: Unmanaged 環境の自前オートスケールなど


# 他サービスとの使い分け

Lambda や EMR、ECS とどう使い分けるの？という。Batch を選択する意味。

## なぜ Batch がでたのか

Azure には AWS より以前に、同名の [Azure Batch](https://azure.microsoft.com/ja-jp/services/batch/) というサービスがありましたが
こちらも狙いは、**汎用的な** 科学技術計算や HPC 基盤のマネージド提供でした。

AWS にも EMR や MachineLearning といったある種の問題解決に特化した
マネージドサービスはありましたが、汎用的なバッチ環境としては
AWS Batch が最も適切なサービスとなりそうです。

## 使い分け

上記のメリットに合致したジョブなら AWS Batch。
悩ましいとしたら、例えば

- Lambda では難しい（運用・開発効率、サーバ性能、タイムアウト、言語）
- EMR 向けに作りこまれたものではない（既存の処理を使いたい）

のならば AWS Batch を使う、など。


# 使ってみよう

実際にジョブを流してみると感覚がつかめると思います。

## ハンズオン

- [[JAWS-UG CLI] AWS Batch #1 環境構築（Managed 編）](http://qiita.com/pottava/items/435c65b1fa72cb643f6e)
- [[JAWS-UG CLI] AWS Batch #1 環境構築（Unmanaged 編）](http://qiita.com/pottava/items/2565418ed919224b8d29)
- [[JAWS-UG CLI] AWS Batch #2 ジョブの作成と実行](http://qiita.com/pottava/items/4151fcb9b14c51f50e9c)
- [[JAWS-UG CLI] AWS Batch #3 より実践的な使い方](http://qiita.com/pottava/items/a1d316e5a622b705efba)
- [[JAWS-UG CLI] AWS Batch #4 環境の破棄](http://qiita.com/pottava/items/6a99eaf17e99243c06a6)