首页 > 其他分享 >基于 fastflow 的一种工作流框架

基于 fastflow 的一种工作流框架

时间:2024-06-07 14:35:32浏览次数:15  
标签:基于 Task reconcile 框架 任务 fastflow 执行 节点 Cloud

Why do we use "reconcile" in Cloud?

让我们思考下在云上为用户提供一种中间件服务,我们需要做什么?

  1. 按照顺序编排申请各类云资源 —— 网络,S3,K8S,计算,存储 ……。
  2. 在 K8S 中自动化部署中间部署
  3. 完成各种初始化配置

可以想象出看出在 Cloud 上为用户提供服务会有大量流程耗时且步骤复杂,涉及需要几十步操作,其中包含云资源申请、k8s 初始化、脚本执行、接口调用等,且相互存在依赖关系。

Cloud 主要通过 web 跟用户交互,假设我们直接把流程直接放到一个同步 http 接口中实现,会遇到什么问题呢?

  • 在请求未成功前,需要一直保持,过于理想,必然会因为网络、用户操作等客观因素难以维系。
  • 服务重启无法自恢复。
  • ……

自然而然我们会采用异步方式提升用户体验,比如创建 MySQL 这个场景:

  • Create MySQL 接口只触发资源申请便立即返回
  • Query MySQL 接口不断轮训集群状态可用。
    而后端便需要在后台异步执行流程完成 MySQL 创建。

基于此设计,便引出了基于终态设计的的 "reconcile" 模型,在当前目前 Cloud 上有两类 "reconcile" 流派:

  • 基于 DB,通过 Timer(Worker) 扫描执行任务
  • 基于 Etcd,使用 Operator 编程模式执行任务
    两者实现思路都是通过 reconcile 的方式处理异步任务,在设计思路上差距不大。

img

What are the problems with using "reconcile"?

  • 运维难度高
    当 "reconcile" 出错时,一般是通过日志去找到报错的点,但是大部分场景下你必须知道上下文才能够解决该问题,这就要求每一位运维同学必须熟悉 worker 的实现逻辑,这是非常困难的。
    而且 Cloud 的业务非常复杂,不仅仅使用一个 worker 就实现单一业务,而是由多个 worker 协作完成,这就加大了分析问题的难度。

  • 迭代效率低
    以 MySQL 的生命周期管理为例,创建、计算扩缩容、磁盘扩容、创建只读等等一系列的独立场景流程,但是 "reconcile" 实现理念是给出预期,下面通过不断的调协达到预期状态,这么多场景耦合在一起实现背景下,在开发过程中很容易出现:

  1. 可能一个 feature 只涉及某个场景,但是所有的场景都必须考虑,否则可能影响其他场景,爆炸半径过大,测试成本高。
  2. "reconcile" 中集成过多的能力,导致代码分支必然膨胀,迭代、维护成本高。
  3. Other
    目前都仅能支持单节点部署,可扩展弱
    流程无版本概念,容易产生版本不兼容问题。
    ……

So what is needed?

我们需要的是一种范式,一种最佳实践,一个解决方案。

  • 流程复杂且相互存在依赖关系 —— 任务编排
  • 优雅的实现任务执行,减少不合理的并发导致的复杂度,降低心智 —— 任务执行调度
  • 高可用,可扩展 —— 分布式
  • ……

所以我们需要的是一种分布式任务编排调度引擎 —— workflow。

Workflow selection

站在巨人的肩膀上,github 中可以找到一些符合的方案

img

作为一个业务团队,引入新的解决方案,我们不单单要考虑技术的成熟度,更需要考虑:

  • Go 体系
  • 开源,不增加额外业务成本
  • 由于没有中台团队支持,在出现问题时有能力兜底能够 owner
  • 不引入额外的中间件,或者新增的中间件依赖足以 cover 运维
  • ……

所以我们选择了性价比最高的方案 Fastflow,可以将其很低成本融入到遗留项目而无需部署、依赖另一个项目。代码精简上手快,在进行一定程度的魔改之后,完全足够支持目前 Cloud 业务。

What is Fastflow?

用一句话来定义它:一个 基于golang协程、支持水平扩容的分布式高性能工作流框架。

Process Define

Fastflow 定义了 Dag、Task、Action 领域模型来描述 DAG 的任务流模型

img

首先 Task1 节点所定义的任务会被执行,当 Task1 执行完毕后,Task2, Task3 两个节点所定义的任务将同时被触发,而只有 Task2, Task3 两个节点都执行成功后,最后的 Task4 节点才会被触发。

  • Dag
    描述了一个完整流程,它的每个节点被称为 Task,它定义了各个 Task 的执行顺序和依赖关系,你可以通过编程 or yaml 来定义它。

  • Task
    它定义了这个节点的具体工作,比如是要发起一个 http 请求,或是执行一段脚本等,这些不同动作都通过选择不同的 Action 来实现,同时它也可以定义在何种条件下需要跳过 or 阻塞该节点。

  • Action
    Action 是工作流的核心,定义了该节点将执行什么操作,一般你都需要根据具体的业务场景自行编写,它有几个关键属性:
    ** Name: Required Action 的名称,不可重复,它是与 Task 关联的核心
    ** Run: Required 需要执行的动作,fastflow 将确保该动作仅会被执行 一次(ExactlyOnce)
    ** RunBefore: Optional 在执行 Run 之前运行,如果有一些前置动作,可以在这里执行,RunBefore 有可能会被执行多次。
    ** RunAfter: Optional 在执行 Run 之后运行,一些长时间执行的任务内容建议放在这里,只要 Task 尚未结束,节点发生故障重启时仍然会继续执行这部分内容,
    ** RetryBefore:Optional 在重试失败的任务节点,可以提前执行一些清理的动作

通过这些领域模型的抽象,我们便拥有了复杂任务的任务编排能力。

Process Execute

img

当你发起运行 Dag 指令时,会以定义的 Dag 为模版,则会为本次执行生成一个执行记录,它被称为 DagInstance,当分发到一个的节点后,再由其解析、执行。
在这边 Parser、Executor 基于 Goroutine 实现,维护执行协程池,可以按需调优。

Distributed

fastflow 是一个分布式的框架,意味着你可以部署多个实例来分担负载,而实例被分为两类角色:

  • Leader:此类实例在运行过程中只会存在一个,从 Worker 中进行选举而得出,它负责给 Worker 实例分发任务,也会监听长时间得不到执行的任务将其调度到其他节点等
  • Worker:此类实例会存在复数个,它们负责解析 DAG 工作流并以 协程 执行其中的任务

img

  • Keeper: 每个节点都会运行 负责注册节点到存储中,保持心跳,同时也会周期性尝试竞选 Leader,防止上任 Leader 故障后阻塞系统,我们也可以实现不同存储的 Keeper 来满足特定的需求,比如 Etcd or Zookeepper,目前官方支持的 Keeper 实现只有 Mongo,但是目前个人已经扩展实现了 MySQL。
  • Dispatcher:Leader节点才会运行 负责监听等待执行的 DAG,并根据 Worker 的健康状况均匀地分发任务
  • WatchDog:Leader节点才会运行 负责监听执行超时的 Task 将其更新为失败,同时也会重新调度那些一直得不到执行的 DagInstance 到其他 Worker

业务实践

  • Fastflow 官方仅支持 Mongo,但是其提供了良好的接口抽象,为了避免引入 Mongo 中间件,开发实现了 MySQL 存储支持
  • Fastflow 不支持单独部署,魔改添加 watcher 角色,使得其他服务服务可以仅进行 dag 下发而不承担任务执行事务。

Before and after comparison

img

Some thoughts

Operator 编程模式必然是有其适用场景的,只是当前我们 Cloud 业务场景下 Workflow 更加契合。
从 K8S 来看,其实 Operator 其实要求其 Reconcile 的 CR 是一个明确的领域模型,即单一职责,当其丰富能力时,往往是新增一个 CR,组合其他 CR,实现其增强能力。

img

这其实要求我们需要小心的设计 Reconcile,不能过度膨胀,精细的设计依赖关系,从而凸显声明式 API 的优势。
其实换个角度来说 Workflow 也是一种 Reconcile 模式,只是 Reconcile 的领域模型是流程,通过不断的 reconcile 直至成功,所以说对于长流程复杂过程的编排,有要求高 SLA 时,workflow 已有的海量的工程落地经验更加切合目前我们的需求。

Future

  • 目前 Fastflow 仅实现了基础分布式任务调度引擎框架,还缺乏很多实用的特性,可以业务跑的更快。
    • 支持 Task Retry
    • 支持多版本
    • 回滚
    • 任意处跳转
    • 父子任务流
    • ……

标签:基于,Task,reconcile,框架,任务,fastflow,执行,节点,Cloud
From: https://www.cnblogs.com/BlueMountain-HaggenDazs/p/18236618

相关文章

  • 【S081】基于SpringBoot实现健身房管理系统 JavaWeb健身房管理系统
    运行截图:登录后台首页会员卡查询会员管理添加会员员工管理添加员工器材管理编辑器材课程管理报名信息项目组成:项目源码:源码获取⬇⬇⬇......
  • 推荐收藏!帮你轻松写好Midjourney提示词的10个结构框架
    最近经常有同学问我,Midjourney的提示词看上去很复杂,不知道如何下手。以下我总结了10个常用的Midjourney提示词结构,希望能帮助你轻松上手提示词。 基础知识开始前,有几件关键的提示词知识需要了解:要有描述性:关于主题、风格、颜色等的细节越多越好。形象思维:像口头描绘......
  • feapder框架爬取ks评论_递归的方式
    importrandomimportreimporttimefromfeapder.db.mysqldbimportMysqlDBimportfeapderdefis_number(string):pattern=re.compile(r'^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$')returnbool(pattern.match(string))classAirSpiderDemo(feapder.Ai......
  • 基于Java+SpringBoot+Mysql实现的协同过滤推荐旅游景点平台设计与实现
    一、前言介绍:1.1项目摘要随着人们生活水平的提高和休闲时间的增多,旅游已成为人们生活中不可或缺的一部分。然而,传统的旅游方式往往存在信息不对称、服务质量参差不齐、行程安排不够灵活等问题,给游客带来了诸多不便。与此同时,互联网技术的快速发展为旅游行业带来了革命性......
  • 基于Java+SpringBoot+Mysql实现的在线电影订票系统设计与实现
    一、前言介绍:1.1项目摘要在线电影订票系统的课题背景主要源于现代社会的信息化、网络化发展趋势以及人们对便捷、高效生活方式的追求。随着互联网技术的飞速发展和普及,人们的生活方式正在发生深刻的变化。在线购物、在线支付、在线预订等网络服务已经渗透到人们日常生活......
  • APP渗透中xposed框架安装及模块安装
    在做APP渗透的时候xposed框架的使用必不可少,工具包在结尾。第一步,下载一个雷电模拟器3版本的(工具包里已经提供),不同版本的对应的xposed可能不同,我这里以我自己安装的为例安装完模拟器后,点击启动模拟器,确认是否开了root权限的将xposed软件拖进模拟器中他会自动安装自动安......
  • 基于prometheus实现SQL监控方案
    需求描述业务上经常会出现这样的问题:客户反馈某个业务今天查不到数据。怎么通过监控提前发现呢?我们的业务场景是这样:在mysql中,每小时、每天,会通过定时任务汇总统计车辆在道路上的作业情况(作业时间、里程、平均速度等)。经常出现,某一个客户某一类型数据没算(表中没有新增数据)。......
  • 基于助听器开发的一种高效的语音增强神经网络
    现代语音增强算法利用大量递归神经网络(RNNs)实现了显著的噪声抑制。然而,大型RNN限制了助听器硬件(hearingaidhardware,HW)的实际部署,这些硬件是电池供电的,运行在资源受限的微控制器单元(microcontrollerunits,MCU)上,内存和计算能力有限。在这项工作中,我们使用模型压缩技术来弥补......
  • 基于 Go 语言实现的 Ollama 大语言模型框架
    大语言模型在现代人工智能领域中扮演着重要角色。Ollama作为一个轻量级且可扩展的框架,帮助开发者在本地机器上构建和运行这些模型。Ollama简介Ollama是一个简单、可扩展的框架,旨在帮助开发者构建和运行大语言模型。它提供了一个简洁的API,用于创建、运行和管理模型。此外,Olla......
  • aws-lambda使用gin框架示例
    假设现在有个需求,项目需要部署到aws无服务器,但是我们的项目以及是成熟项目了,总不能从头开始写吧?所以有了github.com/awslabs/aws-lambda-go-api-proxy这个项目只需要改造路由部分,其他框架官网有示例packagemainimport( "context" "fmt" "github.com/aws/aws-lambda-go/......