共计 6533 个字符,预计需要花费 17 分钟才能阅读完成。
摘要:本文整顿自阿里云高级技术专家宋辛童 (五藏),在 FFA 2022 核心技术专场的分享。本篇内容次要分为五个局部:
- Flink Shuffle 的演进
- 流批交融
- 云原生
- 自适应
- Shuffle 3.0
点击查看直播回放 & 演讲 PPT
一、Flink Shuffle 的演进
在整个 Shuffle 的演进过程中,其实并没有明确提出过所谓 Shuffle 1.0 和 2.0 的概念。但从它的技术倒退经验中,咱们能把它分成如上图所示的两个阶段。
在 Shuffle 1.0 阶段,Shuffle 只具备根底的数据传输能力,Flink 我的项目也处于绝对年老的阶段。
在 Shuffle 2.0 阶段,咱们对 Shuffle 做了一系列优化。
- 在性能方面,咱们对数据的序列化,底层网络的内存拷贝进行了优化,并针对 Batch 场景设计了 Sort-Based Blocking Shuffle,这种 Shuffle 形式可能对磁盘 IO 会更加敌对。
- 在稳定性方面,咱们引入了 Credit-Based 流控机制,这种机制会比本来依赖于 TCP 的反压机制更具稳定性。此外,社区还引入了 Buffer-Debloating 机制,使其可能在反压的状态下缩小数据积压对 checkpoint 的影响。
- 在流批一体方面,咱们将 Shuffle 模块进行 Service 插件化重构,让第三方开发的 Shuffle 实现成为可能。除此之外,咱们还为批场景中的 Remote Shuffle Service 技术铺垫了路线。
综上咱们能够发现,不论是性能还是稳定性,都是 Flink 上大规模生产必备的能力,而流批一体是 Flink 社区过来倒退的次要方向之一。从整个 Shuffle 2.0 阶段,咱们发现 Flink Shuffle 曾经趋于成熟,在生产中体现优异。
说到 Shuffle 3.0 的时候,咱们重点要关注哪些问题呢?或者说随着时代的倒退、技术的提高,对于 Shuffle 又提出了哪些新的挑战呢?这里咱们也列出了三个关键词:别离是流批交融、云原生和自适应。接下来,也会逐个的去跟大家做一个开展的探讨。
二、流批交融
“流批交融”与“流批一体”有什么样的分割和区别?
如上图所示,右边是 Flink 经典的流批一体架构。在这套架构中,Flink 提供了流批对立的 API 表白,而后应用对立的引擎也就是 Flink,进行流和批的数据处理。此外,咱们通常会把实时工作与离线任务调度到同一个集群进行混部,从而晋升研发运维效率和资源利用率。
目前,Flink 流批一体架构次要体现在面向用户的流批一体。如果看引擎的外部,咱们会发现,一个 Flink 工作的流模式和批模式的区别非常明显,而整套架构中也依然存在离线和实时两条数据链路。由此可见,流批一体次要是一个面向用户的概念。
流批交融 ,所谓 Flink 流和批交融的能力,不仅仅是将流和批的技术放在一个引擎当中,咱们心愿能在引擎侧突破流和批的技术边界,既有流技术,又有批技术,同时服务不同的场景。
在流批交融方面,次要有如下两个要点:
- 第一,在批处理场景下,Flink 作为以流式为内核的引擎,岂但借鉴和学习了成熟的批技术教训,还具备很多举世无双的劣势。比方咱们在流解决时,上下游工作同时运行,流式内核引擎可能保证数据不落盘进行间接传输,从而升高 IO 开销,晋升性能。除此之外,在流解决上有基于 checkpoint 的容错机制,它领有更灵便、更精密的容错能力。
- 第二,流式引擎具备批处理的能力之后,反过来也可能更好地服务流解决场景。比方批作业数据通常须要排序,它在状态拜访时具备更好的性能与成果。除此之外,批数据的两头数据会落盘,具备可反复生产的特点,这对容错也有比拟好的晋升。
流批交融次要强调,突破流和批的边界。从引擎侧把所有技术放在一起应用,服务于不同的场景。不难看出流批交融的概念是端到端的事件,贯通执行打算优化、编译、调度、运行、Shuffle、容错等场景,都须要依照流批交融的概念进行扭转和晋升。
Hybrid Shuffle 是一种将流技术利用于批场景的技术。
目前,Flink Shuffle 次要有 Pipelined Shuffle 和 Blocking Shuffle。其中,流式 Pipelined Shuffle 的上下游工作是同时运行的,大幅缩短工作的运行工夫。同时,其数据能够在工作间间接传递,不须要落盘。
然而目前 Pipelined Shuffle 在批场景下,仍处于生产不可用的状态。因为它在上下游同时运行时,资源需要较高。如果同时存在多个工作,每个工作只能拿到一部分资源,很容易造成资源调度的死锁。
批式 Blocking Shuffle 有更好的资源自适应能力。在极限状况下,咱们能够用一个 slot 执行完所有工作。然而它的性能较慢,因为批工作按 stage 调度的形式运行,每个 stage 都须要期待长尾工作实现。其次,它的数据须要全副落盘,导致 IO 开销较大。
由此可见,不论是流式 Shuffle 还是批式 Shuffle,它们在某种特定的状况下,都会呈现资源碎片的景象,即尽管持有资源却不可能调度工作并执行,从而会造成资源节约。
Hybrid Shuffle 是想将流式 Shuffle 跟批式 Shuffle 的特点联合在一起,让用户在写数据时,既能够写入内存通过内存间接进行生产,也能够在内存中寄存不下这么多数据、上游生产不够及时的时候,将数据写入到磁盘当中进行前期生产。通过自适应切换,在上游产出数据的过程中和实现后,上游能够随时生产,从而彻底消除资源碎片的状况。
Hybrid Shuffle 在资源短缺的状况下,上下游的所有工作能够同时运行,它的性能跟流式 Pipeline Shuffle 雷同。在资源受限的条件下,Hybrid Shuffle 能够先让上游执行,将数据落到磁盘之后,上游再进行生产。其资源的自适应性比 Blocking Shuffle 更好。
除此之外,Hybrid Shuffle 在内存跟磁盘之间进行切换,是一种动静的自适应切换,并不是动态的一次性切换。咱们在数据生产的过程中,能够随时在内存写满的状态下,切换到磁盘模式。当内存中的数据被生产,留出更多的空间后,它又能够切换回内存进行生产。
目前,Hybrid Shuffle 曾经在 Flink 1.16 公布。通过测试,Hybrid Shuffle 相比 Blocking,在资源受限的条件下,性能晋升了 7.2%。如果在资源短缺的状况下,Hybrid Shuffle 会比 Blocking 有更大幅度的性能晋升。
接下来,在 Flink 1.17 时,咱们会持续对 Hybrid Shuffle 进行欠缺与优化。次要包含针对播送数据的性能优化,以及对大规模生产中批处理的其余重要个性的兼容。
Single Task Failover 单点重启是将批技术利用于流场景的技术。Flink 在流式工作中,如果一个工作呈现失败,关联的上下游工作都要进行全局重启,能力保证数据一致性,然而这种全局重启的老本较高,特地是一些大规模、简单的作业。
单点 Failover 可能做到当呈现 Failover 时,只对以后失败工作进行重启。目前,咱们反对三种一致性语义,别离是 Best-effort、At-least-once、Exactly-once。一致性的保障越强,相应的开销就越高。其中,Best-effort 须要复原工作状态。为了解决这个问题,咱们采纳分布式部分快照的形式,给每个工作做定时的部分快照,防止全局的同步开销。在 At-least-once 语义下,咱们须要对上游数据进行重放,防止数据失落。在 Exactly-once 语义下,咱们不仅须要对数据进行重放,上游还要对数据进行去重。
不论是重放输出,还是去重输入,都是在 Shuffle 层面实现。它们跟 Blocking Shuffle 的数据落盘半长久化、反对反复生产具备很高的相似性。所以在实践中,咱们是基于现有的批 Shuffle 能力,进行了扩大和二次开发。
目前,Single Task Failover 的工作,仍处于外部实际阶段,At-least-once 语义行将在阿里云外部上线,Exactly-once 则还处于研发当中。
三、云原生
Shuffle 3.0 在云原生场景下的实际。从 Flink 1.9 版本开始,咱们就始终在建设 Flink 云原生部署体系,包含 Native K8s 的部署模式、轻量化客户端的 Application Mode、Native K8s HA 模式,以及 Reactive Scaling 的资源管理形式等等。
Flink 云原生部署体系越来越欠缺。用于 Flink 流式工作的生产也绝对比拟成熟,并通过了大量的生产测验。但咱们在运行批工作时,仍会遇到问题。
其中,最次要的问题是批的 Shuffle 数据存储。在 Batch 工作中,咱们须要对大量的两头数据进行落盘,这个时候就产生了数据寄存在哪的问题。目前 Flink 有两种支流的 Shuffle 模式,即 Internal Shuffle 和 Remote Shuffle。
Internal Shuffle 的数据间接写在 TM,这里有两个问题。
- 第一,资源效率问题。在云生或云计算场境下,资源的弹性伸缩能力是十分重要的。在 Flink 的 Internal Shuffle 中,当咱们把数据写在 TM 本地时,TM 无奈及时开释资源,限度了计算资源的弹性。
- 第二,磁盘老本问题。一个物理机的磁盘在容器化的场境下,咱们无奈准确的界定每个 TM 须要配置多少磁盘空间。如果配置空间较多,老本就较高,会造成资源节约。如果配置空间有余,会影响数据处理的稳定性。
尽管云盘领有动静挂载,共享存储空间等能力,但其老本相比磁盘较高,访问速度也比本地拜访慢一些,同时动静挂载也比拟费时。
综上所述,Internal Shuffle 的问题次要是资源效率以及磁盘老本。
Remote Shuffle 的问题是数据传输开销。本来 Shuffle 数据只须要在两个 TM 之间进行传输,当初咱们须要先从上游的 TM 传输给一个近程零碎,而后上游的 TM 再从近程零碎进行生产,这会让传输的老本至多增加一倍。
此外,咱们岂但须要运维部署 Flink 集群,还须要额定部署一套 Remote Shuffle Service 集群,从部署运维上也会产生一部分老本开销。
最初,Remote Shuffle Service 尽管可能在肯定水平上缓解磁盘空间和磁盘老本问题,因为它能够建设一个 Remote Shuffle Service,同时服务大量不同的 Flink 实例,能够起到削峰填谷的作用,但它并不能从根本上打消磁盘空间的问题。
所以目前 Internal Shuffle 和 Remote Shuffle 都没有十分欠缺的解决方案,来解决 Flink 在云原生场景下 Batch 数据的存储问题。
大家在应用云产品时,常常应用对象存储。基于对象存储的 Shuffle,领有灵便的资源弹性,老本绝对较低。但对象存储往往是不可批改的,上游在写数据的过程中,数据对上游不可见,一旦上游数据可见,上游则无奈对数据进行批改或追加。除此之外,其性能相比本地磁盘或云盘,仍有肯定的差距。
因而在流解决场景下,基于对象存储的 Shuffle 仍面临一些挑战。一方面,须要基于不可批改的对象存储,实现边读边写的能力。另一方面,对象存储很难满足低延需要。尽管对象存储很难独立撑持 Shuffle 数据管理,但当本地磁盘不够时,能够将对象存储作为其余数据存储形式的补充,从而实现性能和老本的平衡。
目前,基于对象存储的 Shuffle,仍处在外部实际阶段,预计在 Flink 1.18 版本公布。
四、自适应
自适应 ,在最新的 Flink 1.16 中,有四种不同的 Shuffle,别离是 Pipelined Shuffle、Hash Blocking Shuffle、Sort-Based Blocking、以及最新推出的 Hybrid Shuffle。将来,Flink 可能会引入 Single Task Failover、对象存储 Shuffle、Merge-Based Shuffle 等等。除此之外,在第三方我的项目中,Flink Remote Shuffle 也是基于 Flink Shuffle 的接口实现。
大量不同的 Shuffle 实现同时存在,也带来了一些问题。用户不晓得如何抉择 Shuffle 类型,应用起来比拟艰难。依据场景抉择适宜的 Shuffle 类型,这须要用户对 Shuffle 外部原理有深刻的理解。抉择 Shuffle 类型之后,在理论生产中,用户对 Shuffle 进行参数调优时,也面临不同的 Shuffle 类型调优参数及原理均有所差别的问题。除此之外,因为有些用户的场景比拟丰盛,可能须要同时应用多种 Shuffle 类型。这些 Shuffle 类型如何进行搭配?其复杂性给用户应用带来了艰难。
在开发者保护方面,随着呈现了越来越多的 Shuffle,工作人员需去保护更多的代码,甚至反复开发。除此之外,Shuffle 外部的复杂度,开始向 Flink 全链路扩散,比方 SQL 编译、调度运行等等。为我的项目的长期的保护,带来了肯定的影响。
为了解决上述问题,咱们提出了三种进步自适应性的办法。
- 第一,复杂性反转。让 Shuffle 适配内部条件,并决定以后须要抉择哪一种 Shuffle 实现,升高操作的复杂性。
- 第二,缩小内部信息依赖。咱们心愿依据理论把握的信息,做出最好的决策。咱们能够把非必要信息,转化为补充信息,同时对能主动获取的信息尽量主动获取,缩小 Shuffle 与其余模块的信息依赖。
- 第三,咱们心愿在运行过程中,依据应用环境的变动,Shuffle 可能主动调整本人的行为,打消不同 Shuffle 类型之间的边界,以适应运行时的动态变化。
五、Shuffle 3.0
最初介绍一下,基于上述关键词,咱们提出的 Flink Shuffle 3.0 架构设计。这套架构被称为自适应的分层存储架构。在这套架构中,咱们将 Shuffle 上下游间的数据交换过程,形象为上游将数据写入某种存储当中、上游再从该存储中抽取须要查问的数据的过程。
在分层自适应存储架构中,蕴含一个写端 Selector 和一个读端 Selector,次要负责向不同的存储介质写数据和读数据。在两头的存储层,暗藏了外部实现细节,具备对立的形象。
在动静自适应方面,写端依照优先级,进行存储层的数据写入。如果遇到空间有余等问题,存储层会反馈以后无奈接收数据,而后持续写下一个优先级的存储层。在读端,咱们依照优先级的程序,顺次去查问想要的数据。通过分层存储加动静自适应的形式,咱们将多种存储层的介质,进行交融和互补,满足咱们在不同状况下的需要。
在存储层布局方面,Local TM 层次要有内存跟磁盘。在 Remote TM 层,用户把数据写到第三方 TM 的内存跟磁盘中,进行治理。此外还有近程存储介质层。
目前,咱们在 Shuffle 3.0 自适应存储架构的摸索中,遇到了如下关键技术问题。
在数据分组方面,不同地位寄存的数据分组形式不同,决定了数据索引构造和文件存储格局的差别。
在数据管理粒度方面,采纳较大粒度在存储层之间切换,升高切换频率和查找代价,不同存储层内适宜不同粒度。在存储层外部,内存存储比拟实用较小的粒度,它对实时可见性的要求较高,治理数据的老本较低。而对于像对象存储这样的近程存储服务,咱们会更关注如何缩小文件数量,偏向于绝对较大的数据管理粒度。
在数据索引方面,数据寄存的地位决定了实用不同的索引形式。比方本地 TM 和近程 TM 上,内存索引的形式查问性能更好。因为对象存储不足内部的服务过程,对数据进行治理。所以咱们基于文件命名的形式,对文件进行简略的 list 操作,依据文件名判断以后想要的数据,是否在文件当中。
目前,Shuffle 3.0 仍处在摸索阶段。将来,在 Flink 1.18 时,社区会推出第一个版本的分层自适应架构存储,蕴含本地 TM 内存、磁盘的存储层,反对远端对象存储能力。后续咱们会逐渐减少流解决、Single Task Failover、近程 TM 的内存 + 磁盘等能力。
点击查看直播回放 & 演讲 PPT
更多内容
流动举荐
阿里云基于 Apache Flink 构建的企业级产品 - 实时计算 Flink 版现开启流动:
99 元试用 实时计算 Flink 版(包年包月、10CU)即有机会取得 Flink 独家定制卫衣;另包 3 个月及以上还有 85 折优惠!
理解流动详情:https://www.aliyun.com/produc…