读数据自助服务实践指南:数据开放与洞察提效17管道编排服务
1.1. 查询或程序的运行时实例称为作业
1.1.1. 作业调度需要考虑到正确的依赖项
1.2. 作业管道需要按照特定的顺序进行编排,从数据接入到数据准备再到数据处理
1.3. 痛点
1.3.1. 定义和管理作业之间的依赖项是即席的,容易出错
1.3.1.1. 数据用户需要在管道演进的生命周期中指定这些依赖项并对它们进行版本控制
1.3.2. 管道所涉及的服务包括接入、准备、转换、训练和部署
1.3.2.1. 在这些服务中监控和调试管道的正确性、健壮性和及时性是很复杂的
1.3.3. 管道编排需要考虑多租户的场景,支持多个团队和业务用例
1.3.3.1. 编排耗时会有所增加,这包括设计作业依赖项的时间和在生产中高效执行作业的时间
1.3.3.2. 编排是确保管道SLA和有效利用底层资源的平衡行为
1.4. 理想情况下,编排服务应该允许数据用户以简单的方式定义和版本控制作业的依赖项
1.4.1. 在幕后,服务应该自动将依赖项转换为可执行逻辑,通过与服务有效集成来管理作业执行,并在失败时重试
1.4.2. 编排服务确保在多租户部署中实现最佳的资源利用率、管道SLA、自动扩展和隔离
1.5. 该服务应易于管理,并在生产规模上支持监控和调试
1.6. 该服务最大限度地缩短了编排耗时,有助于减少整体的洞察耗时
1.7. 编排作业是在高效的资源利用、作业的性能SLA和作业之间的数据依赖项之间进行的平衡
1.7.1. 在实际部署中,确保强大的编排服务有效地与管道服务集成,并在多租户部署中提供自动扩展和隔离至关重要
2. 路线图2.1. 在探索阶段和生产阶段都需要编排管道
2.2. 管道可以一次性调用,也可以根据新数据可用、模式变更等事件进行调度或触发
2.3. E2E管道涉及的技术包括原始数据存储、数据接入和收集工具、一个或多个数据存储和分析引擎、服务数据储存和数据洞察框架
2.4. 调用探索性管道
2.4.1. 在构建过程中,通过构建管道来探索数据集、特征、算法模型和配置的不同组合
2.4.2. 目标是获得快速的响应并在管道上迭代
2.4.3. 探索性管道应在不影响生产管道的情况下运行
2.5. 运行受SLA约束的管道
2.5.1. 在生产中,管道通常是定期设定的,并有严格的SLA完成度
2.5.2. 如果管道没有完成,则需要对其进行调试,以确定是否存在转换逻辑错误、OOM失败、变更管理不当等问题
2.5.3. 数据用户依赖即席工具来管理生产中的管道,并与数据工程团队协作来调试拖慢整个流程的问题
3. 最小化编排耗时3.1. 包括设计作业依赖项、在可用硬件资源上高效地执行它们,以及监控它们的质量和可用性(特别是对于受SLA约束的生产管道)等花费的时间
3.2. 编排服务分为三个不同的阶段:设计阶段、执行阶段和生产调试
3.3. 目标是尽可能减少在每个阶段中花费的时间
3.4. 定义作业依赖项
3.4.1. 作为构建管道(将源数据转换为洞察)的一部分,数据用户需要指定管道中涉及的作业及其依赖项和调用规则
3.4.2. 作业可以即席调用,也可以按计划调用,也可以基于触发器调用
3.4.3. 作业依赖项以DAG的形式表示
3.4.4. 缺少依赖项可能会导致不正确的洞察,是生产部署中的一个重大挑战
3.4.5. 用代码的变化跟踪依赖项的变化很难进行版本控制,虽然依赖的作业可能已经完成,但它可能无法正确处理数据
3.4.6. 作业依赖项不是不变的,而是在管道生命周期中不断演进
3.5. 分布式执行
3.5.1. 作业在分配给编排器的分布式计算机集群上执行
3.5.1.1. 需要对管道DAG进行持续评估
3.5.1.2. 跨多个租户的适用作业排队等待执行,并及时调度以确保SLA
3.5.2. 挑战
3.5.2.1. 要确保多个租户之间的隔离,以便其中一个作业的处理速度下降不会阻塞同一集群上其他不相关的作业
3.5.2.2. 随着管道数量的增加,单个调度器可能会成为瓶颈,导致作业执行的等待时间过长
3.5.2.2.1. 有一种方法将作业在并行调度器上进行分区,可以在可用资源上进行扩展
3.5.2.3. 考虑到作业的异构性,需要利用一系列自定义执行器来执行数据迁移、模式服务、处理和机器学习任务
3.5.2.3.1. 作业执行还需要适当重试执行错误的作业,当崩溃的机器发生故障时,作业需要恢复
3.5.2.4. 执行需要故障转移,然后通过适当的选举机制(leader election)以继续执行
3.5.3. 重新恢复管道的状态至关重要
3.6. 生产监控
3.6.1. 在生产中部署管道后,需要对其进行监控以确保SLA并主动发出问题告警
3.6.2. 趋势分析用于主动发现异常情况,细粒度监控与日志记录相结合可以帮助区分长时间运行的作业和因错误而停滞的作业
3.6.3. 调试根本原因分析需要理解和关联多个系统的日志和元数据
4. 定义需求4.1. 痛点
4.1.1. 如何定义依赖项
4.1.1.1. 准备执行作业所花费的时间
4.1.1.2. 如何发现依赖项以及定义依赖项所需的数据用户专业知识水平
4.1.1.3. 在生产中遇到了多少缺少依赖项的编排问题
4.1.2. 管道的编排方式
4.1.2.1. 提交作业后调度作业的时间
4.1.2.2. 作业完成时间随集群负载的变化
4.1.2.3. 与缺失SLA相关的事件数量
4.1.2.4. 与集群宕机时间有关的问题数
4.1.2.5. 底层集群资源的平均利用率
4.1.2.6. 与编排集群关联的宕机时间
4.1.2.7. 作业错误后自动重试
4.1.3. 在生产中如何有效地监控管道
4.1.3.1. 数据用户是否可以自助进行监控和调试,并了解作业的当前状态
4.1.3.2. 是否可以针对失败作业或缺失SLA的事件提供通知
4.1.3.3. 基于异常告警的误报数
4.1.3.4. 聚合日志和了解作业当前状态的时间
4.2. 操作需求
4.2.1. 管道依赖项的类型
4.2.1.1. 管道可以按计划执行,可以使用用户命令即席执行,也可以由数据可用性事件触发
4.2.1.2. 服务需要为适当的规则和触发器提供支持
4.2.1.3. 数据用户还应该能够指定管道的优先级和SLA
4.2.2. 与部署技术的互操作性
4.2.2.1. 虚拟化技术(如Docker)
4.2.2.2. 作业编程语言(如Python)
4.2.2.3. 作业依赖项规范框架
4.2.2.4. 监控技术框架
4.2.2.5. 基于事件执行的无服务器技术框架
4.2.3. 速度与容量
4.2.3.1. 要支持的并发作业数(最大值和平均值)
4.2.3.2. 作业的平均耗时
4.2.3.3. 租户团队的数量
4.2.3.4. 服务器节点的典型数量
4.2.3.5. 正常运行时间需求
4.3. 功能性需求
4.3.1. 特定于服务的适配器
4.3.1.1. 与一般的shell命令执行器不同,编排器可以实现适配器来调用专门的作业
4.3.2. 作业执行检查点
4.3.2.1. 对于长时间运行的作业,检查点可以帮助恢复作业,而不是重新启动作业
4.3.2.2. 如果在没有任何数据更改的情况下调用作业,检查点还可以重用以前的结果
4.3.2.3. 如果存在具有严格SLA的长时间运行作业,检查点将成为一个关键需求
4.3.3. 资源扩展
4.3.3.1. 分配给编排器的硬件资源应该能够根据未完成请求的队列深度自动扩展
4.3.3.2. 通常适用于具有不同数量和类型的管道的环境,静态的集群规模要么性能不佳,要么在资源分配方面造成浪费
4.3.4. 自动审核和回填
4.3.4.1. 与管道编排相关的配置更改
4.3.4.2. 对于管道不断演进的环境,通用回填功能将允许数据用户创建并轻松管理任何现有的管道回填
4.4. 非功能性需求
4.4.1. 成本
4.4.1.1. 编排在计算上很昂贵,因此优化相关的成本至关重要
4.4.2. 简单的设计
4.4.2.1. 该服务需要是自助式的,以供数据科学家、开发人员、机器学习专家和操作员工等广泛的用户使用
4.4.3. 可扩展性
4.4.3.1. 服务应该是可扩展的,以适应不断变化的环境,并且能够支持新的工具和框架
5. 实现模式5.1. 依赖项编写模式
5.1.1. 简化作业依赖项的规范,防止出现与依赖项相关的错误
5.1.2. 重点是简化数据用户的作业依赖项的编写
5.1.3. 目标是为广大用户提供灵活性、表现力和易用性之间的最佳权衡,以正确定义依赖项
5.1.4. 模式的组合是由开源管道编排器(即Apache Airflow、Uber的Piper、Netflix的Meson和Uber的Cadence(一种通用编排器))实现的
5.1.5. 三大类:领域特定语言(DSL)、UI拖放和过程代码
5.1.6. 工作原理
5.1.6.1. 用户使用DSL、UI或代码指定依赖项
5.1.6.1.1. 该规范使用一组构建块来定义依赖项的触发器和规则,并且规范受版本控制
5.1.6.2. 该规范使用一组构建块来定义依赖项的触发器和规则,并且规范受版本控制
5.1.6.3. 在作业执行期间会持续评估依赖项。当满足依赖项时,将调度作业执行
5.1.7. Apache Airflow实现了基于DSL的依赖项定义
5.1.8. 与代码相比,DSL和UI编写模式的优势在于,它们使编写作业依赖项可以被广大的数据用户访问,避免了实现错误,并且将依赖项逻辑的跟踪与实现分开
5.1.9. 模式的弱点是它们在指定高级依赖项方面存在局限性
5.2. 分布式执行模式
5.2.1. 在多个租户管道的受SLA约束的管道执行之间创建并行性
5.2.2. 调度器
5.2.2.1. 负责调度管道和作业
5.2.3. 工作节点(worker)
5.2.3.1. 负责执行作业
5.2.3.2. Airflow调度器被设计为在Airflow生产环境中作为常驻服务运行
5.2.3.3. 现实世界中的部署容易出现单点故障或饱和
5.2.4. 选举机制
5.2.4.1. 对于任何要作为单例运行的系统组件,选举机制功能会自动从可用的备份节点中选择领导节点(leader)
5.2.4.2. 这消除了单点故障,还减少了部署、节点重启或节点重定位期间产生的任何停机时间
5.2.5. 任务分区
5.2.5.1. 为了管理越来越多的管道,额外的调度器会自动分配一部分管道
5.2.5.2. 当新的调度器联机时,一组管道会自动分配给它,然后新的调度器可以开始调度它们
5.2.6. 硬件宕机时的高可用性
5.2.6.1. 服务必须在不停机的情况下优雅地处理容器崩溃、重启和容器重定位
5.2.7. 分布式执行模式可以根据可用资源进行扩展,平衡服务时间和等待时间
5.3. 管道可观测性模式
5.3.1. 为数据用户提供调试和监控自助服务,以主动发现和避免问题
5.3.2. 提供了对管道进度的监控、违反SLA和错误的告警以及与管道相关的调试帮助
5.3.3. 主动检测问题对于生产数据和机器学习管道至关重要,其目标是帮助管道实行自助管理服务,以便数据用户可以可视化、管理和调试当前和过去运行的作业和管道
5.3.4. 收集
5.3.4.1. 在管道作业中调用不同服务,以聚合监控数据
5.3.5. 分析
5.3.5.1. 关联和分析细节以了解管道的当前状态
5.3.6. 告警
5.3.6.1. 比较异常告警的当前值和历史值
5.3.6.2. 记录用户的反馈以减少误报
5.3.7. 可视化示例
5.3.7.1. DAG视图,列出环境中的DAG,显示已成功、失败或当前正在运行的作业
5.3.7.2. 图形视图,用于可视化特定运行的DAG依赖项及其当前状态
5.3.7.3. 甘特图视图,显示作业持续时间和重叠情况,以确定瓶颈和特定DAG运行的大部分时间
5.3.7.4. 任务持续时间视图,显示作业在过去N次运行中的持续时间,并帮助识别异常值
5.3.8. 另一种模式是在未达到SLA时发出告警
5.3.8.1. 作业或DAG预计完成的时间与平常作业完成时间的差值作为时间间隔,并将此间隔设置成作业级别
5.3.9. Netflix的Meson编排器实现了对管道作业的细粒度进度跟踪
5.3.10. 编排可观察性模式对于生产规模的自助监控和告警,以及满足关键管道的SLA至关重要