批量计算概念介绍
引题:工作负载分类
工作负载的分类方法和标准多种多样,其中 Google 提出的一种简单的分类标准广受认可,即将工作负载分为服务型和批处理型。
- 服务型 service
- 长时间运行,理论上不会停止,对服务质量敏感,主要是线上业务
- 例如 web 服务,e-mail 服务等
- 批处理型 batch
- 运行时间从几秒到几天不等,对短时性能波动相对不敏感,主要是离线业务
- 例如日志分析等
公有云上的批量计算
最初,公有云的工作负载以服务型负载为主,各大厂商也进行了诸多针对性优化。随着云计算的快速发展,越来越多的、不同行业的用户开始使用公有云,批处理型负载显著增加。针对批处理型负载的需求,我们也通过新的产品形式来满足用户。
- 专注业务,支持大规模自动化调度与执行,为用户屏蔽资源细节。
- 调度逻辑,支持 DAG 和优先级调度,满足用户复杂的业务处理逻辑。
- 成本优化,支持资源的动态伸缩,按需分配资源,避免资源浪费,节省成本。
腾讯云 Batch 模型
- 执行单元
- Job,作业,一组关联 Task 的集合
- Task,任务,指明执行逻辑和资源需求
- TaskInstance,任务实例,原子执行单元,一个 Task 可并行执行多份
- DAG依赖
- 通过图拓扑表示 DAG 依赖,Job 是 DAG 图,Task 是点,依赖 Dependence 是边
- Task 是依赖关系的维护单元,不使用 TaskInstance 作为依赖关系的维护单元是为了防止依赖关系爆炸
批量计算完整流程
上一小节是腾讯云 Batch 自身的逻辑模型。本节我们将视角提升到整个处理流程,涵盖调度、计算、存储等方面。流程示意图如下图所示。
- 主要步骤
- 用户上传应用程序和输入文件到对象存储COS上
- 用户提交 Batch 作业
- Batch 创建 CVM 实例
- CVM 实例中启动 Batch agent,从 COS 下载应用程序和输入文件,执行任务实例
- Batch agent 上传输出文件到 COS
- 用户监控 Batch 作业的结果
- 用户在 Batch 作业完成后,从 COS 下载获得输出文件
- 腾讯云闭环
- 整个流程在腾讯云上实现调度、计算、存储闭环
- Batch 提供调度分发能力
- CVM 提供计算能力
- COS 提供持久化存储能力
竞品调研关键问题
在进行产品规划、系统设计的过程中,我们对公有云批量计算产品进行了较为充分的调研,涵盖 AWS, Aliyun, Azure, Google Cloud等友商(其中 Google Cloud Batch 是 Google Dataflow 产品的一部分,专注数据处理,与其他竞品差别较大,不作为主要对比系)。我们从中汲取了大量养分,同时也发现对于一些关键问题和产品规划,不同厂商采用了不同的策略。对此,我们尝试分析背后的产品逻辑和各自优劣,结合目标用户的需求,选择确定了腾讯云批量计算的产品路线。
虚拟机与任务实例的耦合关系
- AWS
- 产品策略:作业与 VM 生命周期解耦。一个 VM 可以运行多个作业,作业分配到 VM 需要装箱。
- 简评:AWS Batch 作业通过容器的方式执行,看起来可以快速启动,但是容器仍然需要运行在 VM 之中,VM 的规格和启停时机难以把握。在试用过程中,我们发现 AWS Batch 容易出现资源浪费和资源“假死锁”问题。客观来说,容器与 VM 2层概念增加了产品逻辑复杂度,而 AWS Batch 并没有完满的处理好这方面的产品逻辑。
- 问题1 资源浪费
- 在一个MaxvCPU(AWS Batch 产品概念,大意为计算环境可使用的 CPU 上限)为16C的环境中,用户先提交一个16C的作业A, AWS Batch 会自动创建一个16C的 EC2 实例执行作业A。然后用户再提交一个8C的作业B,在作业A完成之后,AWS Batch 会复用16C的 EC2 实例执行作业B。AWS Batch的收费策略是根据 EC2 实例收费,这样存在一个问题,在执行作业B的时候,Batch 用16C的 EC2 执行8C的作业,造成了资源浪费。实际上,用户提交作业的规格和吞吐量发生变化是较为常见的事情,这样的 case 比较容易出现。
- 此外,作业执行完成后,EC2 不会立即销毁,通常会保留数十分钟后才会自动释放,对于不持续提交作业的用户,也会造成明显的资源浪费。
- 问题2 资源“假死锁”
- 在一个MaxvCPU为16C的环境中,用户先提交一个8C的作业A,AWS Batch 会自动创建一个8C的 EC2 实例来执行作业 A。然后提交一个16C的作业B。本来预期 AWS Batch 会立即销毁现有的 EC2 实例,然后创建一个新的16C EC2 实例来运行作业B。但是,实际情况要略差于预期,在作业B提交近一小时之后,AWS Batch才创建了16C的 EC2 实例,完成计算环境的调整,以至于用户一度认为 AWS Batch 出现了死锁 bug。虽然最终没有造成死锁,但是 AWS Batch 的调整延迟过大,影响用户体验。
- Aliyun
- 产品策略: Aliyun Batch 分为2种计算环境类型,AutoCluster 自动集群模式和 Cluster 固定集群模式。对于 AutoCluster 模式,任务实例与 VM 生命周期一致;对于 Cluster 模式,虽然任务实例与 VM 生命周期不一致,但是目前仍然采用1对1模式,即 VM 同时只运行一个任务实例。
- 简评:Aliyun Batch,特别是 AutoCluster 模式,产品逻辑简单直接。
- Azure
- 产品策略: 任务与 VM 生命周期解耦。一个 VM 可以运行多个任务。与 AWS Batch 不同,任务分配到 VM 不进行装箱,而是通过参数设置,即一个 VM 可以同时运行 n 个任务,n 可设置。。
- 简评:与 AWS Batch 类似,可能出现浪费资源的问题。不进行装箱,直接为 VM 分配 n 个任务的策略,对于异构化的任务,存在资源评估不准确的问题。
- 用户反馈
- 用户关心业务本身,对耦合关系无明显偏好,希望产品逻辑保持简洁直观,避免资源浪费。
- 腾讯云做法
- CVM 和 任务实例生命周期耦合,一一对应,执行任务实例前夕创建 CVM 实例,执行完成后立即销毁 CVM 实例。保证按需分配和使用资源,节省成本。
- 同时,充分利用 CVM 快速创建优势,快速响应 Batch 业务。
执行单元的层级关系
- AWS
- 产品策略:执行单元为 Job,是原子执行单元,相当于腾讯云的 TaskInstance。
- 简评:保证接口原子性。虽然可以通过指定前序 Job 来表示 Job 间的依赖关系,但是需要用户记录和维护前序 Job 的唯一 ID,并在提交后序 Job 时指定前序 Job 的唯一 ID,相当于用户需要参与维护DAG 关系。同时,AWS Batch 目前无法提供完成的 DAG 视图。
- Aliyun
- 产品策略:Job、Task、Instance三层单元
- 简评:可以在 Job 内部实现 DAG 关系。Aliyun Batch 和 ECS 是两款产品,但是二者的 Instance 和 InstanceId 容易混淆。Aliyun Batch 中存在 InstanceId 的概念,却并非 ECS InstanceId,而是类似 Instance 在 Task 内部索引的概念。
- 产品策略:Job、Task、Instance三层单元
- Azure
- 产品策略:具有 Job 和 Task 两层单元,Job 其实是类似队列或者任务集合的静态概念,Task 是其执行单元。
- 简评:Azure Batch 中的 Task 类似于 AWS Batch 中的 Job,二者优缺点相似。
- 用户反馈
- 希望 Batch 产品可以优雅地处理 DAG 关系,同时对用户简单。
- 腾讯云做法
- 借鉴工作流系统 airflow 的命名方式,采用 Job、Task、TaskInstance 三层执行单元。
- TaskInstance 与 CVM Instance 概念区分。虽然我们目前采用 TaskInstance 和 CVM Instance 生命周期一致的策略,但是二者本身不同,不要混淆。
CVM 用户是否可见
- AWS
- Batch 创建的虚拟机,在其控制台可见
- Aliyun
- Batch 创建的虚拟机,在其控制台不可见,不可直接登录。虽然 Aliyun Batch 提供了内网连通的拓展功能,但是产品体验有待提高。
- Azure
- Batch 创建的虚拟机,在其控制台可见
- 用户反馈
- 多方用户提到友商 Batch 创建虚拟机控制台不可见、无法登录的痛点。当出现问题时较难定位。
- 腾讯云做法
- 保证“搭积木式”的产品观
- Batch 和用户使用相同的方式使用基础产品(例如 CVM),保证基础产品逻辑一致
系统设计
TaskInstance 状态机
腾讯云 Batch 包括 Job、Task、TaskInstance 三层执行单元,TaskInstance 系原子执行单元,这里介绍其状态机。Job、Task 的状态依赖其所含 TaskInstance 的状态,不做展开。
- SUBMITTED
- 已经接收到 Job 并解析拆分。
- 如果存在依赖项,则任务实例进入 PENDING 状态,否则进入 RUNNABLE 状态。
- PENDING
- 驻留在队列中,因为等待其他依赖任务,而无法运行
- 在满足依赖关系后,任务实例将进入 RUNNABLE 状态。
- RUNNABLE
- 驻留在队列中且没有任何未完成依赖项,因为没有资源或者资源配额不足而暂时无法运行
- 当资源足够时,任务实例会被调度运行。
- STARTING
- 任务实例完成调度开始执行和下发,任务实例尚未启动执行
- RUNNING
- 任务实例在计算环境中运行
- 当应用程序退出时,进程退出代码将确定任务实例是成功还是失败。退出代码 0 表示成功,非零退出代码表示失败。
- SUCCEEDED
- 任务实例成功完成,返回码为 0
- FAILED
- 在执行所有可用尝试后,任务实例失败。
系统架构与设计细节
定位为工作流 workflow 系统,适用于 Batch 场景,命名为 Wonderflow。
- Wonderflow API
- 生成唯一 JobId,并将 Job 基本信息提交到数据库中
- 将 Job 完整信息发送至 MQ 中
- 向调用方返回 JobId
- 依赖关系
- Job 拆分时,根据有无依赖,将 TaskInstance 的状态设置为 PENDING 或者 RUNNABLE
- TaskInstance 完成后,会变更关联对象的状态,可能包括 Task、Job、后续 Task、后续 TaskInstance 的状态。
- 调度策略
- 以 owner 为粒度进行集中调度,查询同一 owner、状态为 RUNNABLE 的 TaskInstance,按照优先级排序,逐个遍历
- 如果 TaskInstance 有足够资源配额,则下发执行,将 TaskInstance 信息发送至pre-executor MQ
- 如果 TaskInstance 无足够资源配额,则continue
- owner 之间并行调度;同一 owner 串行调度,避免无意义加锁。
- TaskInstance 存储使用数据库,不使用优先级队列,避免“队列头阻塞”或者优先级变化。
- 以 owner 为粒度进行集中调度,查询同一 owner、状态为 RUNNABLE 的 TaskInstance,按照优先级排序,逐个遍历
- Wonderflow 内部回滚
- pre-executor 和 post-executor 相对复杂,需要内部回滚
- 例如 pre-executor 如果执行失败,进行回滚,销毁已经创建的 CVM 实例
- Wonderflow 与 CVM API 交互
- 支持两种模式,调用内部 CVM API 和 SDK
- 默认采用 CVM API 模式,应用在腾讯公有云场景下
- 可选通过 SDK 模式,与 CVM 用户行为完全一致,意味着用户可以在自己的 CVM 集群中搭建 Wonderflow 系统并直接使用。
- 与CVM实例的交互
- 镜像只需安装 cloudinit,而无须提前嵌入 Batch agent,即可运行批量计算作业
- cloudinit 是业界认可的标准初始化工具,镜像制作标准规范、简易
- 腾讯云计划近期更新主流公有镜像,使之支持 cloudinit
设计原则小结
- “搭积木”
- 批量计算保证基础产品的原生能力,不进行封装或阉割。批量计算和用户使用基础产品的方式一致,保证产品表现一致
- 多调度器并发架构
- 多调度器并发调度,用户(owner)级别并发,类似于 Google Omega 的无锁乐观并发调度架构, 可提升调度系统的吞吐率。用户(owner)内部串行,保证按照优先级调度下发,同时避免无意义加锁。
- 在产品调度策略上,目前批量计算对所有用户采用对等公平策略。如果特定场景(比如私有云环境)需要采用相对公平策略,不同用户具有不同的权重值,则需要增加一个调度组件和一层调度策略,决定优先为哪个/哪些用户进行调度。
- 轻量 API
- API 逻辑轻量,保持快速响应
- 复杂逻辑交由异步消费者完成
- 消费者处理逻辑简洁明确
- TaskInstance 状态机相对复杂,但是每类消费者只做一类事,相当于解耦了状态机。
- 例如,Splitter 负责拆分Job,根据 TaskInstance 有无依赖将状态置为 PENDING 或者 RUNNABLE;Scheduler 只负责调度下发状态为 RUNNABLE 的 TaskInstance,不会考虑依赖关系;post-executor 在销毁 CVM 实例之后,负责变更 TaskInstance 状态和关联对象状态,会将已经无依赖的后续 TaskInstance 状态从 PENDING 变更为 RUNNABLE。
核心功能与产品优势
- 自动托管
- 自动调度、下发、执行海量作业,为用户屏蔽资源细节,专注业务本身。
- DAG 依赖
- 通过 DAG 拓扑形式,描述任务间依赖关系,根据依赖关系保证任务的先后执行顺序。通过简单形式满足用户复杂处理逻辑的业务需求。
- 优先级调度
- 对于无依赖任务实例,基于优先级进行先后调度。
- 计算资源动态伸缩
- 资源与任务实例生命周期一致,根据业务需求动态扩展和释放计算资源,按需分配资源,避免浪费,节省成本。
- 天然集成
- Batch 与腾讯云基础产品天然集成,涵盖计算(CVM)、网络(VPC)、存储(COS/CFS)、安全(安全组)等多个方面,用户业务可在腾讯云上轻松闭环。
- 复用基础产品优势,例如腾讯云 CVM 快速创建。
- 调试 Debug 模式
- TaskInstance 失败后,CVM 实例不销毁,保留现场
- 批量计算创建的 CVM 实例,在 CVM 控制台可见、可登陆,便于用户观察应用运行状态。
批量计算作为一款新产品,可能还存在一些不足,也欢迎大家多多试用 & 反馈问题。
参考
[1] Schwarzkopf, Malte, et al. "Omega: flexible, scalable schedulers for large compute clusters." Proceedings of the 8th ACM European Conference on Computer Systems. ACM, 2013.
[2] Verma, Abhishek, et al. "Large-scale cluster management at Google with Borg." Proceedings of the Tenth European Conference on Computer Systems. ACM, 2015.
[3] Konwinski A D. Multi-agent cluster scheduling for scalability and flexibility[M]. University of California, Berkeley, 2012.
[4] AWS Batch. https://aws.amazon.com/cn/batch/
[5] Azure Batch. https://azure.microsoft.com/en-us/services/batch/
[6] Aliyun BatchCompute. https://www.aliyun.com/product/batchcompute
[7] Google Dataflow. https://cloud.google.com/dataflow/