2017年6月22号,由“京城学堂”和阿里巴巴集团技术发展部主办的“对话科技”系列讲座邀请到了Apache Flink项目的PMC成员,来自德国DataArtisans公司的Till Rohrmann,在北京阿里中心为关注实时计算技术的阿里同学做了一场关于Apache Flink技术发展的精彩分享。这个讲座同时也在阿里内外同步进行了直播,有上千位同学参与观看和互动。
一、讲者简介
Till Rohrmann来自于德国,本科和硕士分别毕业于慕尼黑工业大学和柏林工业大学。其是Flink创始团队的核心人员,目前是Apache Flink项目的Committer和PMC成员,同时也是Flink母公司DataArtisans的技术Leader。
二、相关背景
Flink是新一代的分布式实时计算系统,并于2015年1月成为Apache顶级项目。相比于S4和Storm这些早期的流数据处理引擎,Flink提供了包括Map, Join和Window在内的高级操作算子,保证了在发生故障情况下AT-LEAST ONCE和EXACTLY ONCE的处理语义,并实现了一套批处理和流计算统一的运行框架。Flink还通过反压(Back Pressure)很好的解决了实时计算中不同节点的计算能力差异带来的数据积压问题。此外,Flink为用户程序的中间状态(State)提供了大量支持。在实现有状态的实时计算程序时,用户可以不必关心在发生故障时state如何恢复,以及在并发度改变时state如何重新分发的问题。这些对于state的支持使得Flink相较于其他系统时有较大的优势(Spark streaming直到最近才提供了较弱的state支持)。
三、分享概要
3.1 Flink简介
3.1.1 事件、状态、时间和快照
和其他的流计算处理系统类似,Flink将数据描述成由一组连续的元素构成的数据流,以事件驱动的方式对每个元素执行用户自定义的计算逻辑,并产生新的数据流。 不过Flink通过对State的支持允许用户可以更方便的实现有状态的计算。通过负责State的备份、容错和分发,Flink可以极大地减轻用户开发的负担。
Flink还对计算任务中的时间概念进行了更好的定义。Flink中的时间分为两种,包括处理时间(Processing Time)和事件时间(Event Time)。处理时间即服务器本地时钟的时间,而事件时间则指数据中的真实时间。例如,我们可能在3:00处理了一条发生于2:00的日志。那么3:00就是这个日志的处理时间,而2:00是这个日志的事件时间。事件时钟在实际应用中有着非常重要的意义。在以往流计算系统中需要用户自己去维护事件时间的事件;而Flink则将这些工作抽取了出来,能从乱序到达的数据中正确的推断运行时的事件时刻,允许使用事件时间的用户程序能像处理时间一样触发指定时刻的计算任务。
通过对state进行快照,Flink可以有效预防程序执行过程中可能发生的故障。Flink的快照算法基于分布式系统中经典的Chandy-Lamport算法,并对其进行了优化,使得执行快照对正常流数据的处理不会造成较大的影响。
3.1.2 用户接口
Flink提供了层次丰富的API来允许用户在不同层次上访问state和时间等接口来实现自己的实时计算任务。
在最底层的Process Function中,用户可以直接访问state和时间接口来管理中间状态和注册时间事件。而在上层的DataStream API中,用户的自定义函数可以访问state接口来更新状态,并利用window等算子完成基于时间的数据处理。Table API和Stream SQL则是Flink提供的两种高级声明语言。用户可以和使用数据库一样,使用这些高级语言描述自己的计算任务,而不用关心在管理程序状态和时间事件的具体细节。
3.1.3 主要用户
尽管Flink还是一个非常年轻的项目,不过其先进的设计理念使其正被越来越多的用户接受,用于实时数据流的处理。这些公司分布在各行各业,除了阿里巴巴集团之外,还包括ING,Uber,Netfix和D_TRB等。
3.2 Flink 1.3中的新特性
2017年6月,Flink社区发布了1.3版本。这个版本包含了由103位contributor贡献的1221个提交,更新的代码量超过了30万行。这些数据显示出Flink是一个高度活跃并正高速前进的项目。
3.2.1 增量备份
Flink 1.3中一个极大的改进就是优化了对于大规模程序状态的备份和恢复效率。在Flink 1.2及以前的版本中,Flink在每次备份时都需要将所有程序状态拷贝到可靠存储上。但在实际应用中,程序状态在两次备份之间并不是总被全部更新。很多时间,都只有较小的一部分被更新了。因此,通过增量备份的方式仅对这些发生更新的状态进行备份,可以很好的提高状态备份的效率,从而减少由于故障带来的影响。
在增量备份中,每次checkpoint都会和上次checkpoint进行对比,检查哪些state发生了更新。此时那些未发生更新的数据肯定已经被备份在了可靠存储中了。当前的checkpoint因此只需要保留对其的引用即可。而那些发生更新的state则需要备份到可靠存储中,并记录在checkpoint中。Flink维护一定数据的checkpoint来防止可能发生的故障。当一个不需要的checkpoint被删除时,其对备份数据的引用也会减少。当一个备份数据已经没有被任何checkpoint引用,那么就可以将其删除了。
增量备份首先在Blink中实现,并运用在了阿里巴巴集团的实时计算任务中。之后由Blink团队的 @星罡 贡献给Flink社区。在一个典型应用中,增量备份可以将一次checkpoint的时间从180s减少到只需3-30s,极大的提高了备份性能。
3.2.2 细粒度更新
Flink 1.3 中在提升可靠性方面的另一个重要特性就是细粒度的程序恢复。在以往的运行过程中,任何故障都会导致所有计算节点从上一次成功的checkpoint恢复。而在很多时候,许多计算节点的重启是没有必要的。例如在批处理任务的计算过程中,如果上游的计算结果是已经被写到了可靠存储中,那么我们就可以直接复用这个计算结果,而不用再重新计算。
在Blink团队的 @辅机、 @淘江 和Flink社区的合作下,Flink 1.3现在支持了对细粒度恢复的支持。当发生故障时,Flink将从故障节点出发向前寻找那些结果需要重新计算的节点,并回放在可靠存储上的输入来重启这部分节点。通过减少重启节点的数目,Flink可以很快的从故障中恢复。
3.2.3 Table API和Stream SQL
Flink 1.3中对Table API和Stream SQL也做了大量的改进。现在Flink可以支持更一般的更新流、用户自定义的聚集操作和外部表目录等。Blink团队的 @云邪、@大沙 和 @金竹 在这个过程中为社区做出了巨大的贡献。
3.3 Flink后续工作
为了能够在分布式环境下的提供更高效的实时计算服务,Flink仍然需要非常多的工作。在即将到来的Flink 1.4版本中,Flink社区将重点关注以下几个问题:
更好的state备份管理
目前Flink将state备份到可靠存储上,并要求计算任务在恢复时访问可靠存储来恢复自己的state。当计算任务需要访问远端节点来恢复state时,整个恢复过程就会变得非常漫长。
Flink准备将计算任务的调度和state的位置信息结合起来。在生成快照时,Flink将选择特定的计算节点来存储state,并记录下这些位置信息。而当从故障恢复时,Flink将尽量将任务部署在拥有其state的计算节点上。通过避免访问远程存储,Flink从故障中恢复的时间会大大减少。而利用多个计算节点来存储相同state的备份,Flink也将有机会使queryable state的吞吐变的更高。
提高网络传输的效率
网络传输的效率是影响任务性能的重要因素。Flink 1.4将采取多个手段来提高网络传输的效率,包括
- 减少网络传输过程中不必要的拷贝
- 采取使用事件驱动的网络传输方式
- 实现流量控制来更好的解决由于反压导致的一些列问题。
使用FLIP-6来实现大规模集群上的动态资源
尽管Blink早已经对Flink的资源调度框架进行了大量重构来更好的适应大规模集群的场景,但Flink的社区版本仍然在使用旧的资源调度框架。在Flink 1.4中,Flink社区将和Blink团队合作,把资源调度的实现迁移到能和Yarn以及Mesos结合的更好的FLIP-6框架下。在FLIP-6框架下,Flink也将对Docker和Kubernetes在内的容器有更好的支持
允许更新state的格式
目前用户state的格式发生改动之后,之前程序的state将无法被新的程序使用。这对于一些业务高速发展、程序经常更改的用户来说,是比较难以接受的。Flink将为用户提供有效的转换工具,使得用户在state格式发生变化的情况下,也可以将之前程序的state迁移到新的程序中。
更好的Queryable State
通过queryable state,Flink应用中的state将可以被外部应用访问。这意味着一个Flink应用将不再仅仅是一个数据处理任务,还将成为一个基础数据服务,为其他数据处理任务提供数据查询服务。目前Flink中的queryable state功能还较弱。Flink 1.4希望能对queryable state进行改进,提供更加易用的用户接口,提高整体性能,并提供一定的一致性保证。
更强大的Table API和Stream SQL
Flink 1.4中将为Table API和Stream SQL提供更多的功能,包括数据流和时间谓词的join,用户自定义的表转换和为用户表提供外部queryable的接口等。
四、后记
从2015年底开始,阿里巴巴集团搜索离线团队基于Apache Flink开始了新一代实时计算系统Blink的开发。在早期,Flink在大规模应用场景中的部署有着非常多的缺陷。Blink团队对Flink进行了大量改进和优化,主要工作包括:
- 支持大规模集群上的动态资源调度
- 支持计算状态的增量备份和细粒度恢复
- 提供高级编程语言
这些工作在实际生产任务中取得了非常好的效果,在2016年双十一中很好的支持了搜索、推荐和广告等多个业务。而通过和Flink社区紧密合作,Blink团队也将这些工作回馈给了社区,并在这过程中培养了了多位Flink项目的Committer。
2017年初,阿里巴巴集团成立了统一的实时计算团队,将继续基于Blink来打造具有世界领先水平的实时计算系统,为集团内的各个业务提供高效可靠的服务。在后续的工作中,实时计算团队将继续和Flink社区紧密合作,探索在实时计算中的各类理论和实践问题。实时计算团队也欢迎其他同学能够加入我们,一起为目标而努力。