摘要:本文整理自阿里云智能 Flink 分布式执行负责人、Apache Flink PMC 成员、Flink 2.0 Release Manager 宋辛童老师在 Flink Forward Asia 2023 主会场的分享。本次分享将介绍 Apache Flink 社区未来一年的主要技术方向及规划,以及 Flink 2.0 版本的筹备情况。
点击查看原文视频
Flink 社区目前正在大力投入且未来也会持续投入的工作主要集中在以下三个方向:
第一个方向,流处理上的极致优化与技术演进。Flink 是实时计算领域的事实标准,但这是一种横向的比较,如果纵向分析,即用 Flink 与自身作比较,在实时计算领域现有的技术是否已经足够成熟?是否足够解决用户在生产中遇到的各种各样的问题?从这个角度看,我们还有提高的空间。Flink 社区也会持续推动流处理技术的优化与演进,以保持项目在业界技术的领先性,同时也带动整个业界流处理技术向前发展。
第二个方向,流批一体架构的演进。从 Flink 社区自 2018、2019 年前后开始大力推广的基于 Flink 的流批一体架构,到现在提出的 Streaming Lakehouse 架构,流批一体已经成为 Flink 引擎非常重要的特色,同时也是越来越多的用户选择使用 Flink 的重要原因。Flink 社区也会持续在流批一体架构演进方面进行大力的投入。
第三个方向,用户体验的提升。我们都知道 Flink 项目起源于柏林工业大学的科研项目。在拥有先进的流处理技术架构的同时,由于流处理问题本身的复杂性,以及早期遗留的设计问题,Flink 在易用性上或多或少有一些不尽如人意的地方。Flink 社区充分意识到了一点,也在积极地寻求改进,将用户体验的提升提高到了整个项目未来发展的重要方向之一。
这部分主要介绍在流计算领域,未来要做的工作。
Flink 在流计算领域最重要的技术方向,当属状态管理机制的存算分离架构演进。Flink 提供的是一种有状态的流计算能力,状态管理是 Flink 非常核心的重要能力。云原生时代,大数据上云对 Flink 这样的有状态的计算引擎提出了新的挑战。例如,我们在云上通常会采用统一的资源池,做容器级的资源隔离,其中就包括磁盘空间资源的隔离。当 Flink 的状态存储在本地时,状态本身大小的不确定,会导致容器磁盘空间需求的不确定,进而导致我们难以做出高效的磁盘空间资源管理。此外,云主要的优势之一在于其资源的弹性能力,无论是 Flink 社区还是业界的一些厂商都纷纷推出了 AutoScale、AutoPilot 等能力,使 Flink 可以根据数据流量的实时变化进行动态弹性扩缩容。但在扩缩容过程中需要暂停作业再重启,如果 Flink 的状态存储在本地,在作业恢复时需要完整地将 state 文件拉取到本地,这会极大程度影响弹性扩缩容的作业中断时间。
基于以上因素,Flink 社区目前在大力投入下一代存算分离状态管理架构的设计和讨论。
除了状态管理之外,Flink 社区在流计算方面还在持续地优化和完善一些重要算子的语义和功能,相关内容相对灵散,这里主要列举 Window 和 Join 这两个比较重要的算子。
Window 是流计算中特有的概念,主要用于一些聚合操作。在 Flink SQL 中,我们推荐用户使用表值函数的方式来定义 Window。接下来,Flink 社区也会持续完善基于表值函数的窗口能力,包括支持更多的窗口类型、支持 Change Input 和 Window 的提早或延迟触发等。
另一个重要的算子是 Join 算子,它是数据分析中非常常用的一种算子操作,也往往非常容易成为大规模数据处理当中的计算瓶颈。Flink 社区目前也在探索多种用于 Join 的性能优化技术,包括 Mini-batch Join、Multi-way Join 等。
这部分主要介绍阿里云 Flink 社区未来在流批一体方面的工作。
流批一体的优势在于采用统一的 API 进行流任务和批任务的开发,采用统一的引擎执行,依靠统一的算子实现天然地保证数据口径的一致。统一的 API 是整个流批一体的重要前提。目前 Flink 不论是 SQL 还是 DataStream 的 API 都可以使用同一套 API 进行流批两种不同任务的开发。但是我们发现在很多情况下,这样开发出来的流任务和批任务的代码并不相同,还没有真正做到一次开发,任意切换两种模式运行。
目前 Flink 社区在 SQL 领域正在探讨一种新的流批统一的语法语义,主要是基于物化视图的思想,让 Flink SQL 真正做到一次开发,流批两条链路都可以运行。在 DataStream 方面,由于 DataStream 是一种过程式的面向底层的 API,我们很难完全屏蔽掉流、批两种运行模式的差异。在这方面,社区优化的思路主要是希望明确区分哪些算子/能力具备流批一体的能力,而哪些算子/能力只能服务于特定的流或批的场景,以方便用户更好地开发属于自己的流批一体的业务逻辑。
有了统一的 API 远远不够,要想真正做到流批一体,还需要引擎同时具备优秀的流处理和批处理的能力、性能。Flink 在流处理能力上无疑是业界最好的,社区现在也在大力打造 Flink 的批处理能力,使其成为业界一流的水准。
关于批处理能力提升,这里主要列举了三项工作:
首先,在容错方面,Flink 目前已经可以做到单 task 级别的容错。但是一旦 JM 节点发生故障,仍旧需要重新运行整个作业,包括已经完成计算并且产出结果的任务,代价非常高。目前 Flink 社区已经在就 JM Failover 方案进行讨论,将在 JM 发生故障时恢复已经完成的任务的计算结果,从而大幅降低 JM Failover 的代价。
其次,动态执行优化(AQE)。Flink 社区目前已经能够做到的 AQE 的能力包括动态并发推断、动态分区剪裁等,后续我们也会持续在该方向发力,增加如动态负载均衡、动态拓扑生成、动态算子类型选择等能力。
此外,大规模批处理往往需要依赖存算分离的 Remote Shuffle Service,而 Apache Celeborn 是一个致力于提供通用的大数据 RSS 解决方案的开源项目。而 Flink 自身则在不久之前提出了全新的 Hybrid Shuffle 模式,能够结合流跟批两种不同 Shuffle 的优势,可以说是专门面向流批一体的 Shuffle 模式。Flink 社区目前正在和 Celeborn 社区合作,打造 Hybrid Shuffle 模式和 Apache Celeborn 的集成方案。
有了优秀的流、批处理能力之后,Flink 社区还想进一步打破流、批两种模式之间的边界。
首先先思考为什么会有流和批两种不同的模式?我们观察到,用户在使用流和批模式时,他想要表达的数据处理的业务逻辑没有本质区别,其区别主要是在于对运行时不同性能指标的倾向性。
在流模式下,会更加倾向于低延迟的数据处理能力,我们希望数据处理具有更好的实时性,希望一条数据流过整个系统(从到达系统到产出结果)的时间最短。在追求低延时的过程中,难免会牺牲一部分资源的效率和计算的性能。
在批模式下,实时性要求较低,比起处理每条数据的延迟时间,往往更关注处理完整个数据集所需的时间及资源,也就是更倾向高吞吐性能。
在常见的数据处理场景中,
离线计算场景数据的新鲜度较低,往往更倾向高吞吐。
而在实时计算当中,大部分情况下我们会更倾向于低延迟,但也会存在一些更倾向于高吞吐的场景。如由于数据流量突然增大,处理性能不足,出现数据积压,导致延迟增大;或是在故障恢复需要追数据的情况。在这些情况下,增大的延迟时间已经不能够满足业务需求,比起具体延迟了多少时间,用户往往更关注用多长时间可以把延迟追回,即产生了高吞吐的需求。
此外,在全增量一体的场景下,如 CDC 数据同步,或利用数据回填做状态热启动等场景,我们在全量模式下通常更关注作业的高吞吐性能,而在增量场景下则更关注它的低延迟实时性。
就此,我们提出了流批融合的概念,希望引擎能够自动识别作业对于高吞吐或低延迟的需求倾向性,自动选择合适的流/批模式执行,并且当作业运行过程中状态和需求倾向性发生变化时能够自动进行动态切换。
Flink 社区也会持续完善 Streaming Lakehouse 的架构。图中所示的架构图是由 Flink 流批一体计算能力与 Paimon 流批一体的存储能力相结合,共同打造的一张 Streaming Lakehouse 架构图。
从 Flink 计算引擎的角度,除了前面提到的工作之外,主要还有两方面工作需要完成:一是在面向 OLAP 短查询的性能优化、SQL Gateway 功能完善等;另外,是面向湖存储场景,增强 Flink SQL 的数据管理以及元数据管理的能力。
这部分从用户体验方向出发,而用户体验部分往往落在一些细节上,这里列出了其中一部分比较有代表性的工作。
首先是 SQL 作业的升级,由于升级往往伴随着拓扑的变化,状态的兼容性是长期困扰用户的问题。目前 Flink 社区在这方面已经有了一版解决方案,还处在 MVP 阶段,后续也会持续完善和优化解决方案。
另外,在序列化方面,从功能角度而言,Flink 有非常强大的类型和序列化系统,支持多种序列化器;在易用性方面,目前的序列化机制还有待提高。比如要修改类型和序列化器之间的映射,或修改自动选择序列化器的规则时,往往还涉及到代码的修改。目前 Flink 社区正在进行完全基于配置文件的序列化管理方案的讨论。
关于配置系统,Flink 中有大量的配置项,但一部分的配置项也存在默认值不合理、语义和作用域不明确、暴露内部细节等问题。Flink 社区目前也在重新梳理其配置机制,包括对所有现存的配置项进行重新的评估。
最后,在 API 的演进方面,我们将会淘汰一部分比较陈旧的 API,包括 DataSet API、Scala API,还有 Legacy Table Source/Sink 等。同时对于现有的主要 API,像 DataStream API、REST API、Metrics 等的不足之处进行持续的完善。
可以发现刚才提到的优化很多与 public interface 的修改有关,这会影响到整个项目的向后兼容性,也就引出了我们接下来的话题——Flink 2.0版本。
Flink 在 2016 年推出了 1.0 版本,在 2023 年 10 月推出 Flink 1.18 版本。在七年半的时间中,共发布了 19 个小版本。此次开始筹备新的大版本,最主要的原因是为了引入 API 的非兼容性改动。
Flink 社区对于 API 的兼容性进行了相应的规定。我们有三个不同的 API 级别,分别是@Public、@PublicEvolving 和@Experimental。
在兼容性保证方面,@Public API 保证同一大版本内(即一位版本号相同)兼容,@PublicEvolving API 保证小版本内(即二位版本号相同)兼容,而@Experimental 没有这方面的保证。除了兼容性保证之外,Flink 社区近期还新提出了对 API 迁移周期的要求,即 API 从标记为@Deprecated 到可以删除的最小时间周期。该时间周期对于@Public API 是两个版本,对于@PublicEvolving API 是一个版本。只有同时满足兼容性保证和最小迁移周期的要求,才能够对 API 进行修改。换言之,要修改最新的 1.18 版本当中的@Public API,则至少要在 1.19 版本对其进行 Deprecation,经过 1.19 和 1.20 两个版本迁移周期,才可以在 2.0 版本中进行删除。
基于上述的 API 兼容性的规定,可以得出整个 Flink 2.0 的时间规划大致如下:
Flink 社区已经在 2023 年 10 月推出 1.18 版本;在 2024 年 2 月和 6 月,将分别推出 1.19 和 1.20 版本,以满足 API 迁移周期的需求。同时,我们预计 1.20 版本有可能是 Flink 1.x 系列中的最后版本。考虑到大版本升级的复杂性和工作量,我们计划将 1.20 版本作为长期支持的 LTS 版本,持续为其提供漏洞的修复。我们预计在 2024 年 10 月推出全新的 Flink 2.0 版本。前面提到的未来工作规划中,所有影响兼容性的 API 改动,我们需要严格遵守这一版本规划,而对于一些不涉及到 API 改动的优化和工作,则没有严格的版本对应的要求。
点击查看原文视频
本届 Flink Forward Asia 更多精彩内容,可微信扫描图片二维码观看全部议题的视频回放及 FFA 2023 峰会资料!