Study Notes - Step Functions


Step Functions 在 2016 re:Invent 發佈後我就一直放在心裡,他是令人興奮的功能。本文整理 Step Functions 的學習筆記。


核心概念:狀態機

整理 Step Functions 之前,先用一個例子來說明其核心概念,也就是 有限狀態機 (Finite-State Machine)。主要是整個流程狀態概念有:

  • 狀態 (States):通常是名詞、形容詞、一句話,重點不是動詞。
  • 轉換 (Transition):從 狀態A變成狀態B的轉換過程稱為 過渡 (transition)
  • 開始與結束 (Start / End):狀態機本身必須要有

為了方便說明,用下面這張圖當例子。這是一個專案管理中 Bug 的工作流程圖。圖源自『協同合作系統建制與導入 - 以 Redmine 為例』一文的介紹。

下圖是文章的 Bug 工作流程:

  1. 每個點都代表 狀態 (State)
  2. 每個狀態的 轉換 (Transition) 代表 動作 (Action)
  3. 狀態有 開始結束,這個設計也包含在 Redmine 的狀態定義裡。

過往在實作 Test Framework and Architecture 時,應用到了 Message Queue、Workflow、BatchJob、資源分配策略等,也包含了本文的 Workflow 概念。

應用案例

依照官方提供的 Use Cases,常見的有以下:

  • TRANSCODE MEDIA FILES: 轉檔工作,主要是從 S3 發動,然後透過 Step Functions 控制多個 Lambda 平行執行任務,最後聚合到 DynamoDB
  • SEQUENCE BATCH PROCESSING JOBS: 透過 Step Functions 同時驅動多個 AWS Batch 同時執行任務。例如生物科技的 DNA 分析。
  • SEND MESSAGES FROM AUTOMATED WORKFLOWS: 工作流程,這是我目前研究 Step Function 的主要目的。
  • PUBLISH EVENTS FROM SERVERLESS WORKFLOWS:
  • COORDINATE CONTAINER TASKS IN MICROSERVICES AND SERVERLESS APPLICATIONS: 主要是整合 ECS 或者 Fargate 的應用。
  • ACCESS DATABASES FROM SERVERLESS WORKFLOWS: 有點類似 GraphQL 做的事情,聚合後端的 DDB 查詢,然後整合回去給前端。
  • SEQUENCE STEPS OF MACHINE LEARNING WORKFLOWS: 機器學習的應用
  • COORDINATE EXTRACT, TRANSFORM AND LOAD (ETL) JOBS: 資料處理應用

基礎功能

Step Functions 最重要的核心概念,這些概念都圍繞在狀態機,其主要核心概念分類如下:

  • 程序控制器 (Flow Controller)
    • 循序 (Sequence)
    • 平行 (Parallel)
    • 條件式判斷 (Condition)
    • 時間控制 (Duration、Timeout)
  • 出輸入處理 (Input / Output):包含輸入的資料處理、輸出的資料結果、Log … 等
  • 異常處理 (Error Handling)
    • 執行單元的異常處理器 …
    • Retry 機制
  • 執行單元 (Resource):實際處理的運算單元,主要支援 Activity、AWS Lambda、AWS Services。

在 Step Functions 裡,大概有以下的基本關係:

  • 每個 State Machine 由一個 Definition 和多個 執行 (Execution) 組成。
  • Definition 用 Amazon States Language 描述狀態,格式為 JSON
  • 每次的 Execution 必須提供 名稱 (as ARN) 以及 Input (JSON)

Amazon States Language

AWS 為了實作狀態機,以 JSON-based 定義一套 DSL (Domain Specific Language) ,稱為 Amazon States Language (ASL)。這個資料結構主要在描述多個 State 的類型 (Type)、起始點、結束點、狀態的下一步 (Next)、以及相關的資源 (Resource)。資料結構支援以下 Fields:

  • Required:
    • StartAt: 起始狀態
    • States: 狀態集合,主要的狀態在這裡,後述。
  • Optional:
    • Comment
    • TimeoutSeconds: 最大可以執行的時間,最大值為一年,回覆狀態為: States.Timeout,在 CloudWatch metric 增加 `
    • Version: 預設 1.0

底下是基本的結構:

1
2
3
4
5
6
7
8
9
10
11
12
{
"Comment": "Bug Flow",
"StartAt": "HelloWorld",
"States": {
"State1": {
"Type": " ... ",
},
"State2": {
"Type": " ... ",
},
}
}

範例 - Feature / Bug Workflow

底下兩張圖是我用 ASL 設計的流程 ,主要用來呈現 FeatureDefect or Bug 的工作流程,以此開始作為學習之路。


執行 (Execution)

每個 State Machine 可以同時有多份執行 (Execution)。執行過程中,在 AWS Console 可以看到每個 Step 的 Input / Output / Exception 的結果,如下圖:

這每個 Step 的結果,預設都會寫到 CloudWatch Logs.

Hands-on

準備 State Machine Definition,檔名存成 hello_world.json,如下:

1
2
3
4
5
6
7
8
9
10
11
{
"Comment": "A Hello World example of the Amazon States Language using a Pass state",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Pass",
"Result": "Hello World!",
"End": true
}
}
}

建立 State Machine Definition

1
2
3
4
5
6
7
8
9
10
FUNC_NAME="hello_world"
TS=$(date +"%Y%m%d-%H%M")
DEFINITION="file://${FUNC_NAME}.json"
ROLE_ARN="arn:aws:iam::[YOUR_AWS_ACCOUNT_ID]:role/[STEP_FUNCTION_ROLE]"

aws stepfunctions create-state-machine \
--name "${FUNC_NAME}" \
--definition ${DEFINITION} \
--role-arn "${ROLE_ARN}" \
--tags key=Purpose,value=Lab key=Date,value=${TS}

執行 Step Function,產生一個 Execution。準備一個 input json 然後執行以下:

1
2
3
4
5
6
7
8
9
FUNC_NAME="hello_world"
TS=$(date +"%Y%m%d-%H%M%S")
EXEC_INPUT="file://${FUNC_NAME}_input.json"
SM_ARN="arn:aws:states:us-west-2:[YOUR_AWS_ACCOUNT_ID]:stateMachine:${FUNC_NAME}"

aws stepfunctions start-execution \
--state-machine-arn "${SM_ARN}" \
--name "${TS}" \
--input "${EXEC_INPUT}"

問與答

Q: Step 執行的過程可不可以 Step by Step 手動執行?方便除錯。

目前不行,只能一次拼命衝。

Q: 如果 Execution 執行過程中,在某一個點失敗了,可不可以繼續跑?

目前不行,只能重跑

Q: Step Functions 可否調用其他 Step Function?

可以。


關於非同步架構

分散式系統架構的事件驅動模式不外乎 同步 (Sync)、與 非同步 (Async) 兩大類。同步指的是發出請求的客戶端,會等待處理端的回覆;非同步則是客戶端發出請求後,不會等待服務端回覆。非同步作業架構需要有以下幾種基礎架構:

  1. 訊息仲介 (Message Broker)訊息佇列 (Message Queue)、或者 Pub/Sub:儲存處理的訊息資料,是大量非同步處理的核心架構,著名的實踐有 SQS、RabbitMQ、Kafka、Pub/Sub …
  2. 工作流程 (Workflow): 主要的流程控制器、輸出輸入處理、異常處理、執行單元 … 等。
  3. 批次工作運算單元 (BatchJob):負責執行運算的運算單元。
  4. 資源分配策略 (Resource Stretegy): 為了讓資源更有效地利用,或者滿足一些特定的運算需求 (例如 GPU、I/O Bound),所需要的資源分配策略。
    • 資源調度的實踐有:容器編排器 (Kubernetes)、AWS ECS 的 AWS ECS Task Placement Strategies。

Step Functions 是 AWS 的 工作流程 服務,其核心概念是狀態機。透過狀態機,可以彈性的客製工作流程,同時與其他 AWS 服務整合。

另外 Step Functions 有 Parallel 功能,這功能在 Test Framework and Architecture 文中描述到的 STAX 也有同樣功能,同時在 分散式系統設計 一書的 第七章 分配/聚集 有類似的概念。這些也是促使我研究 Step Functions 的原因。

現在流行的各種 CI/CD Pipeline 的實作,像是 GitlabCI / Jenkins Pipeline 的實作概念也是個非同步事件驅動。


延伸閱讀

站內延伸

官方文件

官方更新


Comments