AWS再入門 Amazon Simple Workflow Service編

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

当エントリはDevelopers.IOで弊社AWSチームによる2015年アドベントカレンダー 『AWS サービス別 再入門アドベントカレンダー 2015』の23日目のエントリです。昨日22日目のエントリは石川の『AWS IAM』でした。

このアドベントカレンダーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

本日23日目のテーマは『Amazon Simple Workflow Service』です。AWSの中でもかなりマニアックなサービスですが、使いどころによってはとても役立つサービスです。

目次

サービスの基本的な説明

Amazon Simple Workflow Serviceとはそもそもどういうサービスでしょう。AWSの公式ドキュメントにはこのように書かれています。

Amazon SWF は、開発者が並行したステップまたは連続したステップがあるバックグラウンドジョブを構築、実行、スケールするのに役立ちます。Amazon SWF は、クラウド内の完全マネージド型の状態トラッカー、およびタスクコーディネーターとみなすことができます。

アプリのステップが完了に 500 ミリ秒より長くかかる場合、処理の状態を追跡し、タスクが失敗した場合は、リカバリまたは再試行が必要であり、Amazon SWF がお役に立ちます。

さあどうでしょう。カタカナが多くてなかなか難解な文章ですね。 一方AWSが提供しているスライドではこのように書かれています。

少しわかりやすくなりました。

つまりAWS SWFとは複数のサーバーでバッチ等の自動処理を行う時に、その順番や振り分け先の管理を行うワークフローサービス、ということです。例えば工場のラインのようなものを想像してみてください。ひとつのラインで粉を一定の量でボウルに入れる、そのボウルがラインを流れていくと別のラインから運ばれてきた卵がそのボウルの上で割られる。それがまた別のラインに運ばれてミキサーで混ぜられ、一口サイズに整形されて、片栗粉を振られておまんじゅうとなる、、、というような一連の作業を管理するシステム、それがAWS SWFの果たす役割、と考えて頂ければ良いかと思います。AWS SWFはAWSの特徴を活かしたシンプルで拡張性の高いワークフローサービスになります。

SWFの特徴

Amazonマネージドである

SWFの特徴としては、SWF自体の管理をAWSが行う、AWSマネージド・サービスである、ということが上げられます。ワークフローサービスというのはつまりワークフローが失敗した場合にどう処理するのか、という部分がキモになります。何回リトライするのか、タイムアウトはどれくらいに設定するのか、それでも失敗した場合は管理者にメールするのか、ロギングはどこまで行うのか、、、という処理に集中する際にワークフローサービス自体が落ちたらどうする、とかリクエストが一辺に溜まりすぎてサービスが重たくなる、とかそういうことはなるべく考えたくありません。SWFを使うとそこら辺のスケールやフェイルオーバー等をAWSがいい感じにやってくれるのでユーザーは処理にのみ集中することができます。

ジョブが分割出来る

バッチ処理を組んだことのある方であればわかるかと思うのですが、バッチはその処理内容によって重要度に随分差がでてきます。計算処理がひたすら重い部分は沢山のサーバーで一気に片付けたいですし、外部APIとの連携が絡むところであれば何十回もリトライするような設計は別の問題を生みます。処理内容の特性によってバッチの構成をそれぞれ変えると安定したバッチ処理が実現できます。

場所を問わない

諸事情によりどうしてもAWSにすぐに移行できないサーバー、というものが出てきます。SWFを使うとオンプレやAWS以外のデータセンターにあるサーバーも管理対象に入れられるので本当に処理のみに注力することができます。

人間の判断も入れられる

これもSWFの大きな特徴のひとつです。人間の判断が必要な場合(選択肢があったり、承認フローが必要だったり)は、人間が処理をするまでワークフローは待ってくれます。これで定期的な自動処理だけではなく日常使用するようなフローにもSWFが使えますね。

ユースケース

ではSWFはどういう時に使うと効率的な業務ができるのでしょう。このようなユースケースを考えてみました。

オンプレを含めたバッチジョブ、人間の判断が混ざるワークフロー

複数拠点に事務所やデータセンターがあり、それぞれのイントラネット内で日常業務を行っている企業でその直近データはクラウドではなくその場所のサーバーに保管されています。 一日一回、各事務所のデータをサマリー処理し本部へ転送、本部内で各事務所のデータをチェック、エラーデータや閾値を超えるような異常データを選別します。通常データは本部内で各DBに保管し、同時に前年同月比、日毎の株価や天候データを外部APIから取得して分析用のベースデータを作成、DWHに格納します。異常データは管理部のDBに保存し管理担当者に内容をメール、管理担当者はダッシュボードより対象データと異常データが起きた理由を確認、承認が否認かを選択します。承認されたデータは本部データにマージされ、否認データは各事務所の責任者に返却されます。

このような場合はSWFが最適ですね。

前提知識

SWFにはいくつかの前提知識が必要です。といってもこれからバッチ処理やワークフローを組む、という方にはそんなに高いハードルではありません。

Java or Rubyの知識

基本的にSWFはAWSのサービスなので各言語用のSDKにSWFを操作するAPIが配布されています。ですがSWFをSDKのみで操作するととても複雑です。そこでSWFを動かす専用のフレームワーク[SWF Flow Framework]というものを使用します。このフレームワークがJavaとRubyでしか提供されていないのでJavaかRubyの知識が必要になる、ということです。 ちなみにバッチ自体はbashで書いても構いません。そのbashを叩くのがこのフレームワークとなる、ということですね。

用語

SWFを身につけるのにはSWFで使われている用語を理解する必要があります。これがなかなかややこしいので、頑張って覚えましょう。
ここでは動画をアップロードし、エンコードやサムネイルの作成などを行ってポータルサイトに公開する、というまでのフローをSWFで管理するユースケースを考えます。

SWF_introduce1

流れ

まずは上のデータの流れを用語を使って書きます。次に書く解説と見比べながら意味を把握していって下さい。
- 動画をアップロードしたタイミングでスターターがワークフローを叩いてエグゼキューションが動きだす - エグゼキューションが最初のタスクをデシジョンタスクリストに投入 - デサイダーがデシジョンタスクリストに投入されたタスクを参照して必要となるアクティビティを決定。アクティビティタスクリストにタスクを投入 - 指定されたアクティビティがアクティビティタスクリストからタスクを確認、バッチ処理を行う - 処理が終了したらアクティビティがタスクリストに結果を投入 - デサイダーがタスクリストから結果を確認、次の処理を決定して次のアクティビティタスクリストにタスクを投入 - これらを繰り返してワークフロー処理を行う - 全ての処理が終わったらデサイダーはワークフローエグゼキューションに処理を返し、ワークフローエグゼキューションが終了処理を行う

スターター

ワークフローをキックするプログラム。キックするごとに違うワークフローエグゼキューションが作られる。

エグゼキューション

ワークフローの基準単位となるインスタンス。ここから最初の処理を行い、ここで最後の処理を行う。

デサイダー

ワークフローがどのように動くべきか、どのアクティビティを選択するかを都度判断する。デシジョンタスクリストを常にポーリングしており、タスクリストにタスクが入った際にそのタスクの内容によってリトライやエラー処理、分散処理等を判断する。

アクティビティ

実際のバッチ処理、ワークフロー処理を担当する。人間の手が入るような処理も書ける。アクティビティタスクリストを常にポーリングしており、タスクが入ったら処理をスタートする。

タスクリスト

タスクを入れるキュー。それぞれのデサイダー、アクティビティごとに別のタスクリストを持っており、それぞれの処理内容や結果セットが入ってくる。

はじめてみよう

それでは早速始めてみましょう。といってもなかなかサクッとテスト的に始めるのは難しいサービスです。通常はこのような段階を踏みます。

SWF_introduce2

[ドメイン]というのはネームスペースのようなもののことです。デサイダー、アクティビティ、エグゼキューション、タスクリストと沢山のコンポーネントを管理するのでネームスペースをわけてクラス管理するんですね。

なにはともあれまずは開いてみましょうマネージメントコンソールからSWFを開きます。さあ、怖がらずに。

SWF_introduce

まず開かれるのがダッシュボードです。上の[Domain]を選択してどのようなワークフローが登録されているかを確認、実行します。
右側には直近のワークフローの結果が表示されます。その下にはタスクリストに実際にどんなタスクが飛んでいるかを確認することができます。

さあ、あとはデサイダー、アクティビティ、エグゼキューションをそれぞれ実装してデプロイすればOKです。ココらへんを1つずつ説明していくと壮大なストーリーになってしまいそうなので、ひとまずサンプルがありますのでそちらを御覧ください。

Ruby版 https://github.com/awslabs/aws-flow-ruby-samples

Java版 http://aws.amazon.com/sdk-for-java/

Javaの場合はEclipseを使用してセットアップするのが便利です。
http://docs.aws.amazon.com/amazonswf/latest/awsflowguide/setup.html

基本、サンプルを改変していくとある程度のものは出来ますので、是非手を動かして一度やってみてください。

ポイント

それぞればらばらな場所にあるバッチ処理をワークフローを使ってまとめるのでポイントとしては「非同期」という部分になります。
JavaのFlow FrameworkではPromise()メソッドとAsynchronous()メソッドが超ポイントとなります。ここの動きを抑えるとFlow Frameworkは8割理解した、といっても過言ではありません。詳しくはこちらにまとめているので御覧ください。

https://dev.classmethod.jp/cloud/aws/reading-workflow-activity/

まとめ

さあ、駆け足でご紹介したSWF、いかがでしたでしょうか。すぐに使えるハードルの低いサービス、とは言いませんが使いこなせると業務の根幹を握るほどのコアサービスとなります。是非とも年末年始で挑戦してみてください!

最後に

以上、『AWS サービス別 再入門アドベントカレンダー 2015』の23日目のエントリ『Amazon Simple Workflow Service編』でした。

明日12/24(木)、城内のAmazon Data Pipelineです。お楽しみに!