一、问题分析概览
流计算作业通常运行时间长,数据吞吐量大,且对时延较为敏感。但实际运行中,Flink 作业可能因为各种原因出现吞吐量抖动、延迟高、快照失败等突发情况,甚至发生崩溃和重启,影响输出数据的质量,甚至会导致线上业务中断,造成报表断崖、监控断点、数据错乱等严重后果。
本文会对Flink 常见的问题进行现象展示,从原理上说明成因和解决方案,并给出线上问题排查的工具技巧,帮助大家更好地应对 Flink 作业的异常场景。
如何分析 Flink问题?
下图描述了遇到 Flink 问题时,建议的处理步骤:
发生问题时,首先要做的是现象记录,即检查作业的运行状态。如果运行状态不是运行中,那肯定没有数据正常输出了,需要进一步从日志中查找问题根因。如果作业在运行中,但是存在近期的重启记录,也表明可能发生了较严重的问题。此时需要整理问题发生的时间线,便于后续定位参考。
作业的吞吐和延时等指标是作业运行是否正常的判断标准。如果一个运行中的作业输出中断、数据量变小等现象,则首先需要观察是否存在严重的背压(也称反压,即 Back Pressure. 后文会细讲如何判定)。如果存在背压,则需根据定位表,找到问题算子并进行瓶颈分析定位。随后还可以查看快照的时长和大小等信息,如果快照过大(例如大于 1GB)或很长时间才完成,则可能对内存造成较大压力。
如果从指标上不能完全判断问题原因,则需要结合完整的日志进行更细致的追查。后文会提到定位异常时常见的报错关键字,可以提升问题定位的速度。如果日志中没有太多有用的信息,则还需要对作业运行的环境进行检查,例如排除是否有其他进程干扰,系统是否被重启过,网络和磁盘是否存在瓶颈等等…
二、常见问题处理
这里我们总结了Flink作业的常见故障、确认方法和建议的解决措施。图中的 JM 表示 JobManager,TM 表示 TaskManager。
1.作业自动停止
现象:本应长期运行的作业,突然停止运行,且再也不恢复。
如果 Flink 作业在编程时,源算子实现不当,则可能造成源算子处理完数据以后进入 FINISHED 状态。如果所有源算子都进入了 FINISHED 状态,那整个 Flink 作业也会跟着结束。
Flink 作业默认的容错次数是 2,即发生两次崩溃后,作业就自动退出了,不再进行重试。当出现此种场景时,TaskManager 的日志中会有“restart strategy prevented it”字样。我们首先要找到作业崩溃的原因,其次可以适当调大 RestartStrategy 中容错的最大次数,毕竟节点异常等外部风险始终存在,作业不会在理想的环境中运行。
此外,旧版Flink(低于 1.11.0)的 RocksDB 内存使用不受管控,造成很容易由于超量使用而被外界(YARN、Kubernetes 等)KILL 掉。如果经常受此困扰,可以考虑升级 Flink 版本到最新,其默认开启自动内存管理功能。
2.输出量稳定但不及预期
现象:作业输出量较稳定,但是不及预期值(正常情况下,每核 5000 ~ 20000 条/秒)。
如果作业输出量达不到预期,我们需要分别从 CPU、内存、磁盘、网络等方面逐一排查是否遇到了瓶颈。
CPU 的瓶颈通常是因为序列化、反序列化开销较大,或者用户自定义算子的某个方法的时间复杂度高。CPU 瓶颈的定位较为简单,使用 JProfiler、j