得物 Flink 内核探索实践

一、前言
随着大数据技术的飞速发展,实时处理能力变得越来越重要。在众多实时处理框架中,Apache Flink 以其强大的流处理能力和丰富的功能集,受到了广泛关注和应用。在实时业务日益增长的趋势下,这促使我们深入探索 Flink 的内核,以更好地保障 Flink 任务的维护。本次分享将重点介绍得物在 Flink 内核方面的探索与实践,探讨如何通过深度优化和定制,实现更加高效和稳定的数据处理能力。
二、读者收益
通过阅读本次分享,读者将获得以下收益:
深入理解 Flink 内核:了解 Flink 的核心架构和关键组件,掌握 Flink 内核的运行机制。
优化实践:学习得物在 Flink 优化方面的实战经验,包括如何通过参数调优和内核定制,提升系统性能。
问题解决方案:掌握处理 Flink 常见问题的方法和技巧,提高在实际项目中应对复杂场景的能力。
实时处理案例:通过实际案例,了解如何在复杂业务场景中应用 Flink,实现高效的实时数据处理。
最佳实践:获得得物在 Flink 应用中的最佳实践建议,帮助在实际项目中少走弯路,提高开发效率。
无论你是刚接触 Flink 的初学者,还是有一定经验的开发者,相信通过本次分享,都能有所收获,进一步提升在实时数据处理方面的能力。
三、自研特性
自研调度器
Apache Flink 是一个开源的流处理框架,调度器是其重要的一部分。
在调度器上,我们新增了一款集合社区各款调度器优点的 DwScheduler。
在流任务生产环境中目前现有的调度并不很理想,在生产中我们常常遇到一些问题,例如:
任务 JobGraph 与资源调度没有直接的联系,难于变化和修改;
不能以 TaskManager 维度均衡分配所有 task 到所有 slot 上;
1.18 以前没有直接动态扩缩容的接口、1.18 以后也没有整体算子同时扩缩容的能力;
流任务调度器没有可以迁移 task/Tm 的迁移计算节点的能力。
DwScheduler 整合了社区调度器的各项优点,并提供了很多适应我们生产情况的特性:
建立了 JobGraph 与资源之间的直接联系,用 JSON 可修改和表示流图信息和资源并进行调度;
能够均衡调度所有 task 到所有 TaskManager 上;
支持动态扩缩容各个算子,并且热更新资源规格的能力;
支持热迁移 task/Tm 的能力。
下面主要从上述的这四个特性上来重点讲解我们的成果。
简化资源调度
背景:常规通过配置任务的高级参数进行提交任务,不利于资源的拓展,以及用户想设置多个 SlotSharingGroup 也无法通用地实现。
SQL/DataStream 任务都可通过我们的 Flink 编译器 Generator 编译完成后生成一个流图资源信息 JSON。

调度器支持通过 JobResourceProfile JSON 信息来进行资源申请。
JobResourceProfile 的信息用户可自由编辑,同样我们也提供了便捷的 UI 给用户操作算子和流图的以及资源的配置。
我们支持配置算子的并行度、最大并行度、SlotSharingGroup,以及资源的 CPU、MEM、堆外内存部分我们也做了合理的管理让用户只需要配置一个比例,自动化设置资源的堆外各项参数降低 OOM 的风险,简化了用户对资源配置的操作难度。
支持接收新的资源资源 JobResourceProfile JSON 重新调度任务,支持同时扩缩容多个 Operator 算子的并行度。
在 JobManager 里我们提供了接收资源变更的 Handler;
DwScheduler 可以接收多元化的 Service 发起过来的资源变更请求;
并且它提供了六个回调接口,不同的 Service 可以通过实现它来执行不同的逻辑。
Flink 支持通过资源 JobResourceProfile+JobGraph 流图提交任务,JM 支持动态接收新的 JobResourceProfile 更新任务资源,可以按标签申请不同的资源机型。
均衡调度 Task
背景:Flink 的 task 分配是基于 slot 维度进行全局调度的,即使配置了 cluster.evenly-spread-out-slots 也同样会有在 Tm 维度上的 task 分配不均衡的问题。
使用自研调度器的情况下,能够使用 JobResourceProfile 提前计算出每个 TaskManager 应该分配多少 task,在此基础上我们实现了自己的 DwSlotSharingStrategy,可以有效的按 TaskManager 来分配 task 个数,而不仅仅是在 slot 层面做到资源的均衡。

在同一个任务使用原生社区调度器和使用我们自研调度器,我们得出了一些数据效果,从 Tm 维度来看 CPU 使用均衡了许多。
从 CPU 使用率上来看,明显均衡了很多,减少了不均衡分配带来的性能瓶颈问题。

TaskManager 热迁移
背景:在日常生产运维中,经常有需要迁移热点机器或故障机器的底层场景,Flink 缺乏这部分的热迁移能力。
自研 Scheduler 为我们解决了这一问题,我们支持了热迁移 TaskManager
同样使用 DwScheduler 提供的六个回调接口以及触发资源变更的请求来完成 Tm 的热迁移
热迁移的 Service 只需要对应地实现下它的功能,不必关心调度的流程

从投入生产迁移 Tm 资源的断流耗时情况来看,几乎能做到断流 1~5s 内的快速迁移:

TmRestart 重启策略
背景:Flink 社区只提供了 FullRestart、RegionRestart,往往在生产环境中我们经常会遇到各种不可抗力 Cancel 用户的代码会超时或堆外有泄漏的情况。
为解决这一问题,我们在 Restart 层面增加了一种 TmRestart 策略:
我们将 Tm Pod 的主进程修改为常驻 Shell,可以在 Cancel 超过一定时间能快速退出进程进行重启,也可以根据 JM 请求的重启参数直接触发 TmRestart;
修改 Pod 的主进程我们需要解决一些问题如:信号量传递给子进程、进程返回码的协调与重新拉起;
另外我们也通过 Shell 主进程对 Tm 进程的 IO 探活、Process D 监控等等;
在重启过程中会对 zk 有一定的重连,我们改造了这部分代码,尝试无法链接上一次的 JM 地址失败后才会去访问 zk 获取最新的 leader 地址。
同时我们也可以调整重新拉起的 Tm 进程的 JVM 参数
在特殊场景通过对 Tm 退出的异常原因进行分析,列如 k8s 判定是 OOM 或是容器等待内存回收的延时分布次数过高,判断重新拉起的 Tm 是否应该进行 JVM 参数适当调整。

TmRestart 重启,可根据任务异常情况、作业配置等按需重启 Tm 进程,支持修改 JVM 的参数。
四、总结
本文主要介绍了以下内容:
Flink 调度器的基本生产优化和改造。
重建 Flink 资源模型和支持热迁移等功能的特性介绍。
Flink 的 Task 分配策略优化和重启逻辑新特性 TmRestart。
*文 / 天然卷
本文属得物技术原创,更多精彩文章请看:得物技术
未经得物技术许可严禁转载,否则依法追究法律责任!
版权声明: 本文为 InfoQ 作者【得物技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/ebcba200c08601af849ff3274】。文章转载请联系作者。
评论