从头构建分布式工作流引擎
近十年来,我一直痴迷于创建工作流引擎。用一堆小型机器构建一台“巨型”机器的想法,对我来说似乎永远不会过时。
工作流引擎的核心是负责在一组机器(通常称为“工作者”或节点)上尽可能快速、高效地执行一系列任务(通常称为“作业”、“管道”或“工作流”)。
构建工作流引擎会面临一系列有趣的挑战。以下是一份简短且并非详尽的清单:
-
您使用什么来编写工作流?您使用通用编程语言吗?例如 JSON 或 YAML 之类的配置类型语言,还是您自己开发 DSL(领域特定语言)?
-
我们如何决定将哪些任务分配给哪些工人,以确保忙碌的工人不会超负荷工作,而其他工人则处于空闲状态?
-
我们如何应对随着计算需求波动而扩大或缩小容量的要求?
-
我们如何处理间歇性任务失败?
-
我们如何处理工人崩溃?
-
当我们需要执行的任务多于可用容量时,我们该如何处理这种情况?
让我们在路上铺些橡胶
我第一次真正需要构建工作流引擎是在一家视频流媒体初创公司工作的时候。当时,该公司将所有视频处理需求外包给了另一家公司。
现有的流程缓慢、昂贵且不稳定。公司会定期收到新内容(电影、预告片、花絮视频、隐藏字幕等等),我们需要一种快速处理这些内容的方法,以便将其上传到服务中供用户欣赏。
此外,现有流程非常僵化,任何改动(例如引入新的音频技术)都需要耗时数月,甚至根本不可能实现。我建议建立一个概念验证项目,以便将工作转移到公司内部进行,幸运的是,我的经理们对此持开放态度。
此时,您可能会问自己,既然有上百万种开源和商业选择,为什么还要构建一个呢?
确实,市面上有很多选择。在决定自己搭建一个之前,我们也考察了不少方案。但至少在当时(大约 2014 年),许多现有的方案要么并非为分布式环境设计,要么更专注于数据处理用例,要么似乎已被废弃,要么就是感觉设计过度,不符合我们的口味。
工作流引擎的初始迭代使我们能够开始处理预告片等“低风险”内容,随着我们对新系统越来越有信心,我们逐渐完全淘汰了旧流程。
后来,一位同事跳槽到另一家需要类似系统的媒体公司,他问我是否愿意过来重新做一遍。我当然答应了。我们的2.0版本在理念上与旧版本相似,但旧版本设计中的许多经验教训都融入到了新版本中。
认识 Tork
在为高度专业化的用例构建了两个专有工作流引擎之后,我渴望看看其他公司(可能用例截然不同)是否也能从类似的系统中受益。因此,我决定构建一个开源版本。
Tork 是一个基于 Golang 的实现,其理念与其闭源前辈非常相似。它可以在笔记本电脑上以“独立”模式运行,也可以根据需要部署到大型机器集群中。
Tork的主要成分是:
-
协调器:负责管理作业和任务的生命周期,将任务路由给合适的工作人员并处理任务执行错误。
-
Worker:负责根据 Coordinator 的指令执行任务。Worker 是无状态的,因此可以根据容量需求的变化轻松添加和移除它们。
-
Broker:Coordinator 和 worker 节点之间的通信方式。
-
数据存储:保存任务和作业的状态。
-
运行时:任务通过运行时执行,运行时将任务转换为实际的可执行文件。由于 Docker 的普及性和庞大的镜像库,目前仅支持 Docker,但计划在未来添加对 Podman 和 WASM 的支持。
你好世界
Tork 作业是用 YAML 编写的:
# hello.yaml
---
name: hello job
tasks:
- name: say hello
image: ubuntu:mantic # docker image
run: | # arbitrary script
echo -n hello world
- name: say goodbye
image: ubuntu:mantic
run: |
echo -n bye world
并通过API提交:
JOB_ID=$(curl \
-s \
-X POST \
--data-binary @hello.yaml \
-H "Content-type: text/yaml" \
http://localhost:8000/jobs | jq -r .id)
查询作业的状态:
curl -s http://localhost:8000/jobs/$JOB_ID | jq .
{
"id": "ed0dba93d262492b8cf26e6c1c4f1c98",
"state": "COMPLETED",
...
}
任务还可以指定自动重试次数、超时、强制执行 CPU 和 RAM 限制以及执行其他有趣的事情,例如条件、循环和并行执行。
如果您有兴趣了解一下,可以在 Github 上找到该项目:
文章来源:https://dev.to/acoh3n/building-a-distributed-workflow-engine-from-scratch-22kl