Slide 1

Slide 1 text

ワークフローオーケストレーション入門

Slide 2

Slide 2 text

2 まとめ ・ワークフローオーケストレーションとは  ワークフロー実行のためのインフラ・システム・トリガーなどの調整を行うこと ・ワークフローツールのトレンド  Airflow以降、モダンデータスタックと呼ばれるワークフローツールが登場 ・ワークフローツールの選び方  実際に使ってみて、チームにとって最も使いやすいツールを選ぶ ・ワークフローツール選定の事例  ML基盤のワークフローをDigdagからPrefectに移行した

Slide 3

Slide 3 text

3 本発表の対象者 ・これからワークフローオーケストレーションツールの導入を検討してる人 ・既にワークフローオーケストレーションツールを使っていて課題感を感じてる人

Slide 4

Slide 4 text

長江 五月 自己紹介 4 @nsakki55 ブログ: https://nsakki55.hatenablog.com/ AWSでML基盤を構築する記事を書いてます 業務 ・MLOps ・MLモデリング ・広告データ分析 CyberAgent AI事業本部 Dynalyst データサイエンティスト マネージャー

Slide 5

Slide 5 text

1. ワークフローオーケストレーションとは 2. 6つのワークフローツールを比較 3. ML基盤へのワークフローツール導入事例(Optional) 目次 5

Slide 6

Slide 6 text

1. ワークフローオーケストレーションとは 6

Slide 7

Slide 7 text

7 ワークフローオーケストレーションとは ワークフローをオーケストレーションすること

Slide 8

Slide 8 text

8 ワークフロー 2つ以上のステップを含む一連の流れ Step 1 Step 2 Step例 : Slack通知・ETL処理・ML学習...etc

Slide 9

Slide 9 text

9 オーケストレーション 複数システム、アプリケーション、サービスを 管理・調整すること Service Service 管理・調整

Slide 10

Slide 10 text

Infrastructure Infrastructure 10 ワークフローオーケストレーション ワークフロー実行のためのインフラ・システム・ トリガーなどの調整を行うこと Step 1 Step 2 Trigger System

Slide 11

Slide 11 text

11 ワークフローオーケストレーションツール ワークフローオーケストレーションを実行するツール Infrastructure Infrastructure Step 1 Step 2 Trigger System ワークフローオーケストレーションツール

Slide 12

Slide 12 text

12 類似語 データオーケストレーション 機械学習オーケストレーション 機械学習ワークフロー データワークフロー ワークフローオーケストレーション ワークフローエンジン(ツールとしての意味) ワークフロー管理 パイプラインオーケストレーション 機械学習に着目 機械学習パイプライン データパイプライン データに着目

Slide 13

Slide 13 text

13 ワークフロー関連の検索数 ワークフローエンジンの呼び名が最も一般的 ワークフロー・データオーケストレーションの検索数が増加 Google Trend workflow orchestration workflow engine data orchestration

Slide 14

Slide 14 text

14 歴史から学ぶ ワークフローオーケストレーションツールの歴史に着目し なぜこのトレンドが来てるかお話しします

Slide 15

Slide 15 text

15 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 16

Slide 16 text

16 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 17

Slide 17 text

17 CRON時代 1974年 UNIXにCRON導入 指定された時刻にコマンドを実行する 0 0 0 1 1 * ./workflow.sh 実行例

Slide 18

Slide 18 text

18 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 19

Slide 19 text

19 リレーショナルデータベース時代 1979年 商用リレーショナルデータベースOracle v2リリース 1995年 Oracleがジョブキューを導入(DBMS_JOB) データベース用コードの定期的な実行をスケジュール DECLARE job_number NUMBER; BEGIN DBMS_JOB.SUBMIT( job => job_number, what => 'BEGIN YOUR_PROCEDURE_NAME; END;', next_date => SYSDATE, interval => 'SYSDATE + 1' ); COMMIT; END; ジョブ例

Slide 20

Slide 20 text

20 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 21

Slide 21 text

21 データウェアハウス・データ統合時代以前 アプリケーション データベース エクセルファイル スクリプトをCRON実行 DBMS_JOB 人手で作業 データソース 集計方法 複数のデータソースごとデータを処理していた

Slide 22

Slide 22 text

22 データウェアハウス・データ統合時代 アプリケーション データベース エクセルファイル データウェアハウス データ統合 Extract Transform Load 複数のデータソースにまたがってデータを処理するのが主流に

Slide 23

Slide 23 text

23 データウェアハウス・データ統合時代 1998年 Informatica 社が PowerCenter リリース スケジュールされたジョブの実行・管理を中心としたツール データ処理のソースとターゲット、2つを繋ぐワークフローの概念を初めて導入 PowerCenterのデータマッピング設定画面

Slide 24

Slide 24 text

24 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 25

Slide 25 text

25 ビッグデータ時代 2006年 GoogleがHadoopをOSS化 2011年 データレイクの提唱・流行

Slide 26

Slide 26 text

26 ビッグデータ時代 アプリケーション データベース エクセルファイル データレイク Extract Load Transform データ活用 オンプレ環境のHadoopエコシステムでデータ基盤構築が主流に

Slide 27

Slide 27 text

27 ワークフローツール第1世代の登場 Hadoopエコシステムを活用するための ワークフローオーケストレーションツールが登場

Slide 28

Slide 28 text

28 ワークフローツール第1世代 2010 Hadoopジョブのオーケストレーションシステム Hadoopジョブやデータ取り込み・書き込みなど 長時間実行されるバッチジョブの管理 Yahoo Oozie 2012 Spotify Luigi 2014 LinkedIn Azkaban Hadoopジョブを実行するバッチワークフローの ジョブスケジューラー 2015 Airbnb Airflow ワークフローをプログラムで作成・スケジュール 監視するためのプラットフォーム 開発 名称 概要

Slide 29

Slide 29 text

29 ワークフローオーケストレーションツールの歴史 CRON時代 リレーショナルデータベース時代 データウェアハウス・データ統合時代 ビッグデータ時代 モダンデータスタック時代 1970~ 1980~ 1990~ 2000~ 2010~ 参考: A Brief History of Workflow Orchestration

Slide 30

Slide 30 text

30 モダンデータスタック時代 Big Query(GCP)がGA Redshift(AWS)がGA Sparkを事業化したDatabrics設立 SnowflakeがGA Kafkaを事業化したConfluent設立 2011 2013 2014 オンプレから安価で高速なクラウドへ ストリームデータ処理技術が発達

Slide 31

Slide 31 text

31 Modern Data Stack Data Stackとは? データ基盤を構成する製品群のこと データベース・BIツール・ETL製品・ワークフローツールなど Modern Data Stackとは? 特定のアーキテクチャ・技術・ソリューションを指す言葉ではない 従来のData Stackの課題を解決しようする技術トレンドの総称

Slide 32

Slide 32 text

32 データ基盤のアーキテクチャ変化 引用: Emerging Architectures for Modern Data Infrastructure: 2020

Slide 33

Slide 33 text

33 ワークフローツール第2世代の登場 DigdagがOSS化 StepFunctions(AWS)がGA Prefectリリース ArgoがOSS化 Dagsterリリース 2016 2017 2018 2019 Cloud Composer(GCP)がGA

Slide 34

Slide 34 text

34 主要ワークフローツールの変遷まとめ CRON RDMS_JOB PowerCenter Oozie Luigi Azkaban Airflow Digdag Argo Prefect Dagster CRON時代 リレーショナル データベース時代 データウェアハウス・ データ統合時代 ビッグデータ時代 モダンデータ スタック時代

Slide 35

Slide 35 text

35 現代のワークフローオーケストレーションの役目 新たなデータスタックが登場してきたが、世代交代は行われず、 様々な技術を組み合わせたデータ基盤が作られている CRONジョブ RDBMSのジョブ ETLツールのジョブ データモデリングのジョブ ストリーミング処理 エクセル手動更新 データスタックごとの管理 運用負荷の増加

Slide 36

Slide 36 text

36 現代のワークフローオーケストレーションの役目 様々なデータスタックと連携し、実行制御を行う CRONジョブ RDBMSのジョブ ETLツールのジョブ データモデリングのジョブ ストリーミング処理 エクセル手動更新 ワークフロー オーケストレーションツール

Slide 37

Slide 37 text

37 ワークフローオーケストレーションツールの機能 実行制御 監視 スケーラビリティ 外部ツール連携 タスクの実行順序の制御やリトライなどを保証する ワークフローの実行状態やログを追跡できる 並列処理や柔軟な計算リソースの拡張を行う データベースやETLツールなどと容易に連携可能 機能 概要

Slide 38

Slide 38 text

38 ワークフローオーケストレーションツールの恩恵 ワークフローオーケストレーションツールを導入することで変わることは? 以降はワークフローツールと略称します

Slide 39

Slide 39 text

39 データパイプラインの課題 イベントログ マスターデータ 手動入力データ 抽出 クレンジング 結合 書き込み 抽出 抽出 データ変換 Slack通知 書き込み 型変換 手動実行 バッチ実行 チームA管理 チームB管理 スクリプトで 処理を記述 レポートテーブル 日販管理

Slide 40

Slide 40 text

40 データパイプラインへのワークフローツール導入 手動リトライ 自動リトライ 自前実装 タスク定義のみ 複数箇所 一箇所 チームごと管理 チーム横断で管理 エラー対応 実行順序制御 実行ログ確認 データサイロ化 導入前 導入後

Slide 41

Slide 41 text

41 機械学習パイプラインの課題 生データ 抽出 前処理 学習 学習 学習 評価 デプロイ 特徴量ストア モデルストア 並列学習 実験管理 GPU利用 jupyter notebookに処理を記述 データサイエンティストが管理

Slide 42

Slide 42 text

42 機械学習パイプラインへのワークフローツール導入 jupyter notebook スクリプト 個人 チーム 困難 比較的容易 パイプライン管理 運用者 複数モデル管理 導入前 導入後

Slide 43

Slide 43 text

43 ワークフローとDAGの関係 Directed タスク依存関係は一方向のみ Acyclic タスクが正常実行されると再実行されない Graph ワークフローをタスク(ノード)と依存関係(エッジ)で表現

Slide 44

Slide 44 text

44 ワークフローとDAGの関係 A B C D A B C D DAG Not DAG 実行順序を事前に決定できる 最後のタスクが成功=ワークフローの成功 メリット

Slide 45

Slide 45 text

45 なぜDAGがワークフローツールに普及したか 初期のワークフローツールはHadoopジョブをマークアップ言語で記述 MapReduce マークアップ言語 Map Task Reduce Task 出力 入力 Map Task Map Task YAML・XMLなど ループ・相互依存 を表現できない 全てのワークフロー をDAGとして表現 DAGにする必要性がない説もある You Probably Don’t Need a DAG

Slide 46

Slide 46 text

2. 6つのワークフローツールを比較 46

Slide 47

Slide 47 text

47 ワークフローツール一覧 awesome-workflow-engines に100個のワークーツールがまとまっている

Slide 48

Slide 48 text

48 比較するワークフローツール AWS Step Functions

Slide 49

Slide 49 text

6つのワークフローツールの特徴比較 Step Functions 特徴 シンプル 手軽 k8sと連携 Python DAG 活用事例が豊富 自然なPython 記法での開発 データ運用に特化 サーバレス AWSサービス ワークフロー 実装言語 digファイル (YAML) k8s manifest (YAML) Python (Operator) Python (Flow) Python (Job) GUI操作 JSON 利用形態 OSS OSS OSS SaaS クラウドマネージド OSS SaaS OSS SaaS クラウドマネージド 学習コスト 低 中 高 高 高 低

Slide 50

Slide 50 text

50 GitHub Star数の推移 ☆33635 ☆14049 ☆14112 ☆9703 ☆1277

Slide 51

Slide 51 text

51 Airflow ワークフローをDAGとしてプログラムで作成・ スケジュール・監視するためのプラットフォーム

Slide 52

Slide 52 text

52 SaaS・マネージドサービスとして提供 Astronomer Amazon Managed Workflows for Apache Airflow Cloud Composer Azure data factory

Slide 53

Slide 53 text

53 Airflowの構成 DAG Operator Task Operator Task

Slide 54

Slide 54 text

54 実装例 import json import pendulum from airflow.models.dag import DAG from airflow.operators.python import PythonOperator with DAG( "tutorial_dag", default_args={"retries": 2}, description="DAG tutorial", schedule="@daily", start_date=pendulum.datetime(2021, 1, 1, tz="UTC"), catchup=False, tags=["example"], ) as dag: DAGの設定 DAGコンテキストマネージャを使用 ・実行スケジュール ・リトライ

Slide 55

Slide 55 text

55 実装例 def extract(**kwargs): ti = kwargs["ti"] data_string = '{"1001": 301.27, "1002": 433.21, "1003": 502.22}' ti.xcom_push("order_data", data_string) def transform(**kwargs): ti = kwargs["ti"] extract_data_string = ti.xcom_pull(task_ids="extract", key="order_data") order_data = json.loads(extract_data_string) total_order_value = 0 for value in order_data.values(): total_order_value += value total_value = {"total_order_value": total_order_value} total_value_json_string = json.dumps(total_value) ti.xcom_push("total_order_value", total_value_json_string) def load(**kwargs): ti = kwargs["ti"] total_value_string = ti.xcom_pull(task_ids="transform", key="total_order_value") total_order_value = json.loads(total_value_string) Python Operatorで実行する 関数を作成 タスク間のデータ受け渡し

Slide 56

Slide 56 text

56 実装例 extract_task = PythonOperator( task_id="extract", python_callable=extract, ) transform_task = PythonOperator( task_id="transform", python_callable=transform, ) load_task = PythonOperator( task_id="load", python_callable=load, ) extract_task >> transform_task >> load_task Operatorのインスタンスを作成 DAGの作成

Slide 57

Slide 57 text

57 UI 実行履歴

Slide 58

Slide 58 text

58 UI Runごとの実行詳細

Slide 59

Slide 59 text

59 UI 実行ログ

Slide 60

Slide 60 text

60 Digdag 複雑なタスクパイプラインの構築・実行・ スケジュール・監視に役立つシンプルなツール

Slide 61

Slide 61 text

61 Digdagの要素 Task Executor Task sh> py> email> bq> loop> redshift> if> ECS Operator Regisotry Command Executor

Slide 62

Slide 62 text

62 Digファイルでワークフローを記述 timezone: UTC +setup: echo>: start ${session_time} +disp_current_date: echo>: ${moment(session_time).utc().format('YYYY-MM-DD HH:mm:ss Z')} +repeat: for_each>: order: [first, second, third] animal: [dog, cat] _do: echo>: ${order} ${animal} _parallel: true +teardown: echo>: finish ${session_time} YAML記法 + Dig独自の記法

Slide 63

Slide 63 text

63 YAMLの利点・欠点 利点 ・シンプルで理解しやすい ・プログラムでパース・生成できる ・シンタックスハイライト可能 欠点 ・外部ファイルのincludeができない ・変数の埋め込みができない ・プログラムが書けない 参考: DigdagはなぜYAMLなのか?

Slide 64

Slide 64 text

64 YAMLの欠点を補填 利点 ・シンプルで理解しやすい ・プログラムでパース・生成できる ・シンタックスハイライト可能 欠点 ・外部ファイルのincludeができない ・変数の埋め込みができない ・プログラムが書けない 参考: DigdagはなぜYAMLなのか? Digファイルならできる

Slide 65

Slide 65 text

65 タスクグループと変数 引用: https://docs.digdag.io/architecture.html タスク内で変数を使用 タスクのまとまり(グループ) を1つのタスクとして扱う

Slide 66

Slide 66 text

66 実装例 timezone: UTC schedule: daily>: 01:00:00 _export: !include: 'plugin.yml' workflow_name: sample_workflow task_date: ${moment(session_time).utc().format("YYYYMMDDHH")} +prepare: sh>: tasks/prepare_data1.sh +analyse: _export: bar: 2 +sub_step1: py>: tasks.MyWorkflow.analyze_step1 +sub_step2: py>: tasks.MyWorkflow.analyze_step2 スケジュール設定 外部プラグイン読み込み・変数宣言 ・JavaScriptプログラム展開 タスクグループ

Slide 67

Slide 67 text

67 UI ワークフロー一覧 ProjectにWorkflow が紐づく Digファイルの バージョン 実行結果 実行時間

Slide 68

Slide 68 text

68 UI Taskごとの 実行結果

Slide 69

Slide 69 text

69 Argo Kubernetes上で並列ジョブを調整するための オープンソースのコンテナネイティブワークフローエンジン

Slide 70

Slide 70 text

70 Argoの要素 Template Template Workflow Workflow Template ・実行ワークフローを定義 ・タスクの内容を定義 ・6種類のタイプがある

Slide 71

Slide 71 text

71 6種類のTemplate Container Script Resource Suspend Steps Dags 実行コンテナの設定 コンテナ内での実行スクリプトの設定 k8s clusterリソースを操作 一時停止 タスクの一連の実行ステップを作成 タスクの依存関係を作成 Definitions Invocators

Slide 72

Slide 72 text

72 実装例 apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: Name: sample-workflow spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - - name: step2 template: gen-random-int - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: ["step1"] - name: gen-random-int script: image: python:alpine3.6 command: [python] source: | import random i = random.randint(1, 100) print(i) ワークフローの開始テンプレートを指定 spec.entrypointは必須 テンプレートの実行順序 タスクの処理内容であるテンプレートの作成

Slide 73

Slide 73 text

73 UI ワークフローの一覧履歴

Slide 74

Slide 74 text

74 UI 実行詳細画面

Slide 75

Slide 75 text

75 Prefect ワークフローの構築、観測、優先順位付けを行う オーケストレーション・オブザーバビリティプラットフォーム Pythonコードをインタラクティブなワークフローに変換する 最も簡単な方法

Slide 76

Slide 76 text

76 Hybrid Model 引用: https://www.prefect.io/security#hybrid-model ワークフローの実行制御を行う ワークフローのコード管理・ 実行環境を用意する 責任分担 Prefect User

Slide 77

Slide 77 text

77 Prefectの要素 ワークフロー定義.py Prefect Cloud Worker Deployment Storage Work Pool ・実行インフラ ・コード管理 ・スケジュール  などの設定 docker S3 GCS Git kubernetes ECS Cloud Run ワークフロー実行 開発環境 管理画面 コード管理 実行環境 ワークフロー実行制御 LapTop

Slide 78

Slide 78 text

78 実装例 from prefect import flow, task import pandas as pd import s3_client @task def extract()-> pd.DataFrame: s3_client.download_file(S3_BUCKET, file_name) data = pd.read_csv(file_name) return data @task def transform(data: pd.DataFrame)-> pd.DataFrame: data_transformed = data.groupby('column') return data_transformed @task def load(data: pd.DataFrame): s3_client.upload(S3_BUCKET, file_name, data) @flow def etl(file_name: str): extracted_data = extract(file_name) transformed_data = transform(extracted_data) load(transformed_data) if __name__ == "__main__": etl(file_name=”sample.csv”) Task Task Task Flow Task = Python関数 Flow = 関数の依存関係 Task Flow Python関数に@taskデコレータをつけると Prefectはタスクとして認識する @flowデコレータでFlowとして認識する タスクの出力を次のタスクの入力にできる python workflow.py でCLI実行可能

Slide 79

Slide 79 text

79 GCP GKEでの実行例 ワークフロー定義.py Prefect Cloud Worker Deployment Kubernetes Work Pool Kubernetes Job 開発環境 管理画面 コード管理 実行環境 GKE Artifact Registory prefect.yaml image自動ビルド

Slide 80

Slide 80 text

80 実装例 name: flows prefect-version: 2.13.8 build: - prefect_docker.deployments.steps.build_docker_image: id: build-image requires: prefect-docker>=0.4.0 image_name: "asia-docker.pkg.dev/{{ $GCP_PROJECT_ID }}/repository/auto-image" tag: latest dockerfile: auto platform: "linux/amd64" push: - prefect_docker.deployments.steps.push_docker_image: requires: prefect-docker>=0.4.0 image_name: "{{ build-image.image_name }}" tag: "{{ build-image.tag }}" pull: - prefect.deployments.steps.set_working_directory: directory: /opt/prefect/auto_image ワークフローのコード管理・実行インフラ環境・スケ ジュールなどの設定を prefect.yaml に記述 ワークフローのdocker imageをビルド 自作のDockerfileでビルドも可能 Container Registryにpush ワークフロー実行時の コード取得先の設定

Slide 81

Slide 81 text

81 実装例 definitions: tags: &common_tags - "gke" work_pool: &**common_work_pool** name: "gke" job_variables: image: "{{ build-image.image }}" deployments: - name: "auto_image" tags: *common_tags schedule: - cron: "0 0 * * *" entrypoint: "flows/etl.py:etl" work_pool: *common_work_pool work poolの設定 実行したいインフラ環境 をここで変更 tag, scheduleなどを設定

Slide 82

Slide 82 text

82 UI 失敗した実行履歴 実行環境ごとの履歴 全体の実行状況

Slide 83

Slide 83 text

83 UI タスク依存関係 アプリケーションログ リトライ タスク詳細

Slide 84

Slide 84 text

84 Dagster データリネージ統合・可観測性・宣言的プログラミング・ テスト機能を持つ、開発ライフサイクル全体をサポートする クラウドネイティブなデータパイプラインオーケストレータ

Slide 85

Slide 85 text

85 Dagsterの要素 Asset テーブル・機械学習モデル・ ファイルなど永続オブジェクト Op パイプラインを構成する タスクの処理をモデル化したもの 引用: https://docs.dagster.io/guides/dagster/how-assets-relate-to-ops-and-graphs

Slide 86

Slide 86 text

86 Dagsterの要素 Software-Defined Assets 存在する必要があるAsset(データに関する オブジェクト)やAssetの作成・更新方法を コードで表現したもの データ管理に特化

Slide 87

Slide 87 text

87 Asset実装例 from dagster import asset from typing import Dict import pandas as pd from sklearn.linear_model import LinearRegression @asset def iris_dataset() -> pd.DataFrame: return pd.read_csv( "https://docs.dagster.io/assets/iris.csv", names=["sepal_length_cm","sepal_width_cm","petal_length_cm","petal_width_cm","species"] ) @asset def logistic_regression_model(iris_dataset: pd.DataFrame) -> LinearRegression: x = iris_dataset[["sepal_length_cm", "sepal_width_cm", "petal_length_cm", "petal_width_cm"]] y = iris_dataset["species"].map({"Iris-setosa": 0, "Iris-versicolor": 1, "Iris-virginica": 2}) return LinearRegression().fit(x, y) @asset def accuracy(logistic_regression_model: LinearRegression) -> Dict: return { "intercept": logistic_regression_model.intercept_, "coef": logistic_regression_model.coef_, } @assetデコレータでAssetを 作成 関数引数がAssetの依存関係 を表す

Slide 88

Slide 88 text

88 Asset Job実装例 from dagster import ( Definitions, load_assets_from_modules, define_asset_job, AssetSelection, FilesystemIOManager, ScheduleDefinition, ) from . import assets all_assets = load_assets_from_modules([assets2]) iris_job = define_asset_job("etl_job", selection=AssetSelection.all()) schedule = ScheduleDefinition( job=iris_job, cron_schedule="0 0 * * *", ) io_manager = FilesystemIOManager(base_dir="data") defs = Definitions( assets=all_assets, schedules=[schedule], resources={"io_manager": io_manager}, ) assetの実行・監視を 行う集合 Asset Asset Asset Asset Job asset jobの作成 実行スケジュールの作成 job実行に関わる設定をまとめる

Slide 89

Slide 89 text

89 クラウド環境で実行する(Dagster Cloud) Serverless Hybrid Dagsterがインフラ環境を提供する フルマネージドタイプ型 ユーザーのインフラ環境で実行する Dagsterは実行のみを行う

Slide 90

Slide 90 text

90 Hybridの構成 Agent Code Location Deployment docker kubernetes ECS ワークフロー実行 開発環境 管理画面 コード管理  実行環境 Job実行制御 GitHub Actions Deployment main feature dagster_cloud.yaml

Slide 91

Slide 91 text

dagster_cloud.yaml 91 AWS ECSでの実行例 Agent Code Location Deployment ECR ECS ワークフロー実行 開発環境 管理画面 コード管理  実行環境 Job実行制御 ECS Service main 公式のGitHubテンプレート GitHub Actions 公式のCloud Formation

Slide 92

Slide 92 text

92 code locationの設定 location_name: my_dagster_project image:{aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/dagster-image:latest code_source: package_name: my_dagster_project build: directory: ./ registry:{aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/dagster-image:latest container_context: ecs: run_resources: cpu: "1024" memory: "2048" ECS Taskの起動image imageが自動buildされる ECS Taskのリソース設定 dagster_cloud.yaml Dagster Cloudに登録するcode locationの設定ファイル

Slide 93

Slide 93 text

93 UI Asset関係図

Slide 94

Slide 94 text

94 UI 実行ログ

Slide 95

Slide 95 text

95 StepFunctions AWS Lambda関数と他のAWSサービスを組み合わせて ビジネスクリティカルなアプリケーションを構築できる サーバーレスのオーケストレーションサービス AWS Step Functions

Slide 96

Slide 96 text

96 Step Functionsの機能 引用: https://aws.amazon.com/jp/step-functions/use-cases/ AWS Lambda+AWSサービス の一連の処理を制御

Slide 97

Slide 97 text

97 実装例(管理画面操作) 実行AWSサービスを選択 AWSサービスを繋ぎ合わせる 各ブロックの設定

Slide 98

Slide 98 text

{ "StartAt": "RunCrawler", "States": { // 中略 "ETL": { "Type": "Task", "Resource": "arn:aws:states:::glue:startJobRun.sync", "Parameters": { "JobName": "etlandpipeline" }, "Next": "StartTrainingJob" }, "StartTrainingJob": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:547760918250:function:lambdaModelTrain", "ResultPath": "$", "Next": "CheckStatusTraining" }, "CheckStatusTraining": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:547760918250:function:lambdaModelAwait", "ResultPath": "$", "Next": "CheckTrainingBranch" }, // 中略 } } 98 実装例(JSON) 実行するAWSリソースを指定 JSON形式のAmazonステートメント言語で ワークフローを記述 次の実行タスクの指定

Slide 99

Slide 99 text

99 UI 実行サービスのリンク リトライ タスク状態の可視化 エラータスクの詳細

Slide 100

Slide 100 text

ワークフローツール選定 どのワークーフローツールを選べば良い?

Slide 101

Slide 101 text

はじめに考えること 実践的データ基盤への処方箋〜 ビジネス価値創出のためのデータ・システム・ヒトのノウハウ P146 第2章 データ基盤システムの作り方 から引用 はじめに考えることは、 データ基盤「専用」のワークフローエンジンにするか、 会社のワークフローエンジンに「相乗り」するかです

Slide 102

Slide 102 text

既存のワークフローツールに「相乗り」する場合 データ・MLエンジニアがワークフローツールの実行環境を運用しなくてよい 事業システムの処理とデータ基盤の処理を1つのワークフローで制御できる データ基盤のワークフローを気楽に変更できなくなる 事業システム側のワークフローツールがレガシーすぎて使いにくい場合がある Pros Cons

Slide 103

Slide 103 text

選定基準 実践的データ基盤への処方箋〜 ビジネス価値創出のためのデータ・システム・ヒトのノウハウ P148 第2章 データ基盤システムの作り方 から引用 選択の基準になる考え方はシンプルに 「使いやすい製品かどうか」です

Slide 104

Slide 104 text

使いやすいとは? 技術・人・カネの制約の中でプロダクト課題を解決できる 最も扱いやすいもの

Slide 105

Slide 105 text

6つのワークフローツールの特徴比較 Step Functions 特徴 シンプル 手軽 k8sと連携 Python DAG 活用事例が豊富 自然なPython 記法での開発 データ運用に特化 サーバレス AWSサービス ワークフロー 実装言語 digファイル (YAML) k8s manifest (YAML) Python (Operator) Python (Flow) Python (Job) GUI操作 JSON 利用形態 OSS OSS OSS SaaS クラウドマネージド OSS SaaS OSS SaaS クラウドマネージド 学習コスト 低 中 高 高 高 低

Slide 106

Slide 106 text

106 誰にとって使いやすい? Step Functions 既存システムをkubernetesで構築してる シンプルなバッチ実行で十分 ワークフローツールにお金をかけたくない AWSを利用していて 小規模なワークフロー実行で十分

Slide 107

Slide 107 text

107 Airflow・Prefect・Dagster? 結局、どれが1番つかいやすい?

Slide 108

Slide 108 text

108 Redditの議論 Orchestration: Thoughts on Dagster, Airflow and Prefect? Dagster: 11 Prefect : 5 Airflow : 1 AirflowからDagster・Prefect・他ツールに移行した人が多い 好意的なコメント数

Slide 109

Slide 109 text

109 個人的な評価 実際に使ってみて、チームが使いやすいツールを選ぶのが大事 最も有名でノウハウが多く世に出てる安心感がある ハマりどころが多い 拡張性が高くPythonに慣れてる人には使いやすい 情報が少なく学習コストが高い データエンジニアの寄り添った仕様 公式ドキュメント・実装例が整備されてる

Slide 110

Slide 110 text

3. ML基盤へのワークフローツール導入事例 110

Slide 111

Slide 111 text

111 運用していたMLワークフロー N個のモデルの学習が毎日M回行われる データ取得 前処理 学習 オフライン評価 オンライン評価 データ分布評価 モデルデプロイ データ取得 前処理 学習 オフライン評価 データ取得 前処理 学習 オフライン評価 ・・・ 並列 実行 でワークフローを定期実行

Slide 112

Slide 112 text

112 運用していたMLワークフロー ECS Taskでタスクを実行 データ取得 前処理 学習 オフライン評価 オンライン評価 データ分布評価 モデルデプロイ データ取得 前処理 学習 オフライン評価 データ取得 前処理 学習 オフライン評価 ・・・ ECS Task ECS Task ECS Task ECS Task でタスク実行を制御

Slide 113

Slide 113 text

113 ワークフローツールをなぜ変える必要があった? ・ML以外のバッチ処理がdigdagで運用されていた ・管理するワークフローツールは1つにしたかった ・最初はシンプルな学習バッチを動かせればよかった ・MLワークフローに徐々に機能追加 で運用できていた 運用課題が出てきた

Slide 114

Slide 114 text

114 ワークフロー運用の課題 巨大YAMLの認知負荷が増加 タスク1 タスク2 タスクごとのログをCloud Watchで確認 ワークフロー画面にログを集約したい タスク1 データ タスク間のデータの受け渡しが困難 タスク2

Slide 115

Slide 115 text

115 ワークフロー運用の課題 柔軟な条件分岐を行いたい タスク2 タスク1 タスク3 条件A 条件B ワークフローのテストを書きたい

Slide 116

Slide 116 text

116 ワークフロー選定要件 既存システムとの相性 リアルタイムログ監視 開発がしやすい ワークフローを柔軟に組める 低コスト SageMaker Pipeline Step Functions

Slide 117

Slide 117 text

117 なぜPrefectを選択した? 既存システムとの相性 リアルタイムログ監視 開発がしやすい ワークフローを柔軟に組める 低コスト タスクをECS Taskで実行できる Web UIからログ追跡可能 Pythonで実装 if elseを使って書ける Prefect 2.0から値上がり😰

Slide 118

Slide 118 text

118 Prefect移行後のイメージ 118 オンライン評価 データ分布評価 モデルデプロイ データ取得 前処理 学習 オフライン評価 ・・・ ECS Task ECS Task ECS Task ECS Task ・ワークフローツールだけ変える ・既存のアプリケーションコードは変えない 変える・変えない要素

Slide 119

Slide 119 text

119 ML基盤のPrefect運用 全体構成

Slide 120

Slide 120 text

120 ML基盤のPrefect運用 パラメータの活用 実行時パラメータに計算リソース・ 学習設定を渡す 特定のモデルだけ学習する、 メモリを一時的に上げる などの動的な変更が可能

Slide 121

Slide 121 text

まとめ 121

Slide 122

Slide 122 text

122 まとめ ・ワークフローオーケストレーションとは  ワークフロー実行のためのインフラ・システム・トリガーなどの調整を行うこと ・ワークフローツールのトレンド  Airflow以降、モダンデータスタックと呼ばれるワークフローツールが登場 ・ワークフローツールの選び方  実際に使ってみて、チームにとって最も使いやすいツールを選ぶ ・ワークフローツール選定の事例  ML基盤のワークフローをDigdagからPrefectに移行した

Slide 123

Slide 123 text

123 参考文献 ● A Brief History of Workflow Orchestration ● An Introduction to Workflow Orchestration ● https://github.com/meirwah/awesome-workflow-engines ● Data Orchestration: Definition, Parts, Examples, and Benefits ● データエンジニアが最初に学ぶべき3つのポイント:「ETL」「データモデリング」「ワークフロー」 ● [最終回] データパイプラインのためのワークフロー管理 ● データパイプラインの管理 ● Argo vs Airflow vs Prefect: How Are They Different ● DigdagはなぜYAMLなのか? ● 実践的データ基盤への処方箋〜 ビジネス価値創出のためのデータ・システム・ヒトのノウハウ ● Orchestration: Thoughts on Dagster, Airflow and Prefect?