Flink 在腾讯的使用与稳定性优化实践
分享嘉宾:邱从贤 腾讯 高级开发工程师
编辑整理:徐将锋 顺网科技
出品平台:DataFunTalk
导读: 本次分享的主题是Flink作业的稳定性优化实践。主要包括以下内容:
- Flink在腾讯的应用
- Flink的稳定性介绍
- 稳定性的优化实践
- 总结&展望
01 Flink在腾讯的应用
首先和大家分享下Flink在腾讯的应用。
1. Oceanus平台概括
Oceanus平台是腾讯内部基于Flink的一站式实时计算平台。在Oceanus中主要支持Jar作业、SQL作业以及画布作业,其使用的主要资源是Yarn和k8s,数据存储主要在HDFS,上游主要是基于MQ,下游是MQ以及各种Service。
2. Flink典型应用场景
上图是Flink在腾讯内部的一个典型场景。
上图是Flink的另外两个典型的应用:左边是特征的生产,右边是线上服务使用Flink做的一些应用实例。
02 Flink的稳定性介绍
1. Flink作业概括
上图是Flink运行时的概括图:
- Master主要负责作业调度
- 资源池主要是Yarn和K8s
- HA相关主要由Zookeeper负责
- Task主要运行用户逻辑
- Task 在Checkpoint时将状态数据备份到HDFS上
2. 稳定性介绍
Flink作业稳定性可能的影响方面如下所示:
①第三方系统
- Yarn:Container数量、Container的资源使用(CPU,Memory,链接数等)
- HDFS:存储量、访问量
- Zookeeper:连接数
②Flink
- 控制链路:Master和Worker通信、Checkpoint流程
- 数据链路:数据热点(可能导致数据倾斜)、反压、Flink Bug、用户逻辑异常
03 稳定性优化实践
在实践过程中,针对前文所述的影响因素,我们将稳定性优化分为三个方面:
(1)减少故障,尽量避免故障发生
①优化Zookeeper HA协议
②Checkpoint小文件合并:减少HDFS文件数量以及Namenode 的 RPC数量
(2)降低影响,在无法避免故障发生的情况下,尽可能降低对任务的影响
①空间上,尽可能减少受影响的Task的数量
- 单点重启:只影响出问题的Task
- Master failover:在Master failover的时候,整个作业不需要重启,使用新的Master去接管整个作业的状态,可以减少作业重启上带来的影响
②时间上,减少作业故障的时间
- 作业启动加速:尽可能使任务快速的恢复
(3)快速发现&恢复
①自动诊断系统:先于用户发现问题,发现一些共性问题
接下来对其中一些重点优化项目展开讲解。
1. 减少故障(优化Zookeeper HA协议)
上图中优化前Master会和Zookeeper进行通信连接,同时也会向Zookeeper订阅leader信息。每个Taskmanager也会和Zookeeper进行连接,同时订阅相关leader信息,从而获取当前最新 master,Taskmanager和Zookeeper在整个作业生命周期都会与Zookeeper建立连接。实际上通过分析可以知道TaskManager和Zookeeper的连接并不需要长期持有,因为TaskManager和Master会有正常的心跳连接,这一点也可以用来衡量当前的Master是否是最新的Master。另外,所有的TaskManager与Zookeeper会有非常多的连接,从而导致Zookeeper压力过大。
在优化后,整个作业只有Master和Zookeeper保持通信连接,TaskManager和Zookeeper会断开连接,这样就会大大减少Zookeeper的压力。在优化之后,需要解决的最大问题是当Master failover之后TaskManager如何去感知到新的Master信息。
下面通过一个Master failed的流程来介绍新旧Master切换的过程。
上图标红的Master表示发生了故障。第一步Master发生了故障之后,资源管理平台会拉起一个新的Master并向Zookeeper注册leader信息。
第二步TaskManager和旧的Master会发生心跳超时,当心跳超时之后,TaskManager会和Zookeeper重新建立连接获取新的Master信息。TaskManager在获取到新的Master信息的时候,会和新的Master进行连接汇报自己的状态信息。最后TaskManager在连接成功之后,会断掉与Zookeeper的连接,这样就能保证TaskManager与Zookeeper不需要一直保持连接。
从优化后的数据来看,单个计算集群中Zookeeper的连接数会从万级别降低到几百的级别,大大减少了Zookeeper的压力。
2. 降低影响(单点重启)
下面介绍在无法避免failover的情况下,如何降低作业的影响。下图为目前Flink在Task failover的流程。
首先Master会监听到Task的状态,当Master感知到Task Failed之后会取消掉所有Task的执行(global failover,如果开启了 region failover 则只需要取消失败 task 所在 region 的所有 task)。然后Master会从Zookeeper上拉取最新的状态信息,以及从HDFS上拉取最新的checkpoint数据,再调度拉起所有的Task。
这样就会造成当Task-2失败之后,还会重新调度拉起Task-1和Task-3的执行,会导致整个作业数据的断流。从用户角度,可能会看到一个指标降为0的情况发生。
我们希望当Task-2出现故障之后,仅重新调度Task-2,其他的Task还继续运行。在这里会遇到一些 挑战 ,如下图:
①挑战一
Flink是基于Buffer而非Record进行网络传输,可能会导致一个Record跨多个Buffer。
②挑战二
可能会因为反压机制导致一些Task无法响应其他请求。
接下来 通过一个Task Failed的流程来介绍整个单点重启的过程 。
上图有5个Task,其中 Task-3是失败的Task,Task-2是Task-3 的上游,Task-4是 Task-3 的下游。Task-3失败时,上游Task-2会感知到故障,清掉将要发生给 Task-3 的buffer数据,下游Task-4同样也会感知到Task-3的失败并且清掉buffer数据,从而避免写入到Task-3的Record和从Task-3中读取的Record不完整的情况。
Master在感知到Task-3失败的时候,会将上游的状态全部清理掉,并且会重新调度新的Task-3。新的Task-3会重新去连接上游的Task-2,等待Task-2将数据写入。等到Task-3有数据产生的时候,Master会告知下游Task-4去重新连接Task-3,这样就完成了整个数据链路的建立。
下图是对于 不同粒度Task失败重启的延迟时间 :
可以看到全局重启的情况,不停的失败会导致数据参差不齐。使用单点恢复的方式,就只影响一个task,其它task不受影响。从作业粒度也可以看到,单点重启保证了作业大部分数据得到有效处理。右图是业务方实测的数据断流的时间,在使用全局重启的情况下,container感知失败,恢复,再加上业务侧恢复,总共要138秒;而使用单点重启后,整个过程业务都感知不到断流情况。
但注意这里的单点重启是有损的,可能存在丢数据的情况。
3. 快速恢复(启动加速)
接下来介绍 在任务Failed之后如何去做更快的恢复 。
上图是通过实际作业测试得到的数据,我们发现在作业失败恢复的过程中,主要有三个瓶颈需要去解决,来加快作业启动速度:
- Master主线程需要处理大量的RPC请求
- Container需要去拉取大量的文件
- Container需要即时申请
针对这三个瓶颈分别做相应的优化:
- 优化分布式协议,去掉不必要的RPC请求
- 合并依赖文件,将多个小文件变成单个大文件
- 允许额外的备份Container,不需要即时去申请
在优化之后,整个的恢复过程会从200秒减少到48秒。
4. 快速的感知问题(reactive->proactive)
接下来介绍,如果无法减少影响以及影响的确发生了,如何去更快地感知问题。
在问题产生的时候,平台会发出告警通知用户,然后用户去查看日志排查问题,人工解决相应问题。在这个过程中,可能会存在日志或者指标的缺失,特别是排查checkpoint相关的问题时。而且这是一个耗时耗力的过程,需要一些专家经验沉淀。对于一些通用的问题,比如整个集群出问题了,也无法做出提前的感知,无法比业务提前感知。
上图大圆圈Heartbeat Timeout和Checkpoint Expire表示收到的告警信息,小圆圈是发出的这个告警可能的原因。在这种情况下,我们必须要去看日志信息或者Yarn指标来确定原因。这个流程对于经常查问题的人来说也需要几分钟,这是一个比较耗时的情况。
基于上面问题,在我们内部增加了一些帮助查问题的系统,如下图:
左边的这张图,我们加了Logs日志系统、Metrics指标系统和Traces系统(将感兴趣的Event汇报到中心存储系统)。我们通过Logs、Metrics和Traces来进行综合诊断,诊断之后得到最终结果。比如,Heartbeat Timeout是因为OOM Killer引起的,Checkpoint Expire是因为Sycn snapshot引起的,我们可以直接给出相关的原因和建议。
04 总结&展望
前文中,我们从稳定性的影响因素出发,从减少故障、降低影响以及快速发现&解决三大方面来进行优化。
在未来,我们会去考虑进一步的优化,比如:
- 如何在不丢失数据的情况下,保证单点重启。
- 在降低影响的情况下,会去考虑大状态的快速恢复。
- 对于快速发现和恢复,要在当前的诊断系统基础上继续完善,对于常见的问题给出具体的指引,让用户知道如何去恢复,甚至做到自动恢复,减少人工的介入。
分享嘉宾
邱从贤 腾讯 高级开发工程师
腾讯高级开发工程师,Apache flink committer,现在腾讯负责 Flink 相关工作,有丰富的大数据开发实践经验。