9.6 如何处理 Flink 中数据倾斜问题?
在大数据计算场景,无论使用 MapReduce、Spark 还是 Flink 计算框架,无论是批处理还是流处理都存在数据倾斜的问题,通过本节学习产生数据倾斜的原因及如何在生产环境解决数据倾斜。
9.6.1 数据倾斜简介
分析一个计算各 app PV 的案例,如下图所示,圆球表示 app1 的日志,方块表示 app2 的日志,Source 端从外部系统读取用户上报的各 app 行为日志,要计算各 app 的 PV,所以按照 app 进行 keyBy,相同 app 的数据发送到同一个 Operator 实例中处理,keyBy 后对 app 的 PV 值进行累加来,最后将计算的 PV 结果输出到外部 Sink 端。
可以看到在任务运行过程中,计算 Count 的算子有两个并行度,其中一个并行度处理 app1 的数据,另一个并行度处理 app2 的数据。由于 app1 比较热门,所以 app1 的日志量远大于 app2 的日志量,造成计算 app1 PV 的并行度压力过大成为整个系统的瓶颈,而计算 app2 PV 的并行度数据量较少所以 CPU、内存以及网络资源的使用率整体都比较低,这就是产生数据倾斜的案例。
随着业务的不断发展,如果 app1 的日志量暴增,单个节点的单个并行度已经承担不了计算 app1 PV 的任务,此时如何来解决呢?对于不了解数据倾斜的同学看到 Flink 任务出现了延迟,结合之前学习的反压章节,定位整个 Flink 任务的瓶颈在于 Count 算子,所以认为 Count 算子的并行度不够,于是解决思路就是调大 Count 算子的并行度至 4 来提高 Count 算子的计算能力,调大并行度以后发现 Flink 任务的吞吐量并没有提升,而且通过反压机制定位到系统的瓶颈还在于 Count 算子,难道 Count 算子的并行度需要从 2 调大到 10 吗?No,上述情况就算把并行度调大到 100,依然不能解决任务瓶颈。为什么出现这种情况呢?要计算各 app 的 PV 数据,那么相同 app 的数据必然要发送到相同的 Operator 实例去处理,现在只有两个 app,最多只能分配到两个并行度上去执行,如果 Count 算子的并行度大于 2,意味着肯定有一些并行度分配不到数据,所以上述情况调大 Count 算子的并行度不能解决问题。那使用 Flink 如何来解决数据倾斜呢,我们先学习 Flink 中如何来判断是否发生了数据倾斜。
9.6.2 判断是否存在数据倾斜
这里再通过一个案例来讲述 Flink 任务如何来判断是否存在数据倾斜,如下图所示,是 Flink Web UI Job 页面展示的任务执行计划,可以看到任务经过 Operator Chain 后,总共有两个 Task,上游 Task 将数据 keyBy 后发送到下游 Task,如何判断第二个 Task 计算的数据是否存在数据呢?
如下图所示,通过 Flink Web UI 中 Job 页面的第一个 Subtasks 选项卡,可以看到任务的两个 Task,点击 Task,可以看到 Task 相应的 Subtask 详情。例如 Subtask 的启动时间、结束时间、持续时长、接收数据量的字节数以及接收数据的个数。图中可以看到,相同 Task 的多个 Subtask 中,有的 Subtask 接收到 1.69 TB 的数据量,有的 Subtask 接收到 17.6 TB 的数据量,通过 Flink Web UI 可以精确地看到每个 Subtask 处理了多少数据,即可判断出 Flink 任务是否存在数据倾斜,接下来学习 Flink 中如何来解决数据倾斜。
9.6.3 分析和解决数据倾斜问题
在 Flink 中,很多因素都会导致数据倾斜,例如 9.6.1 节描述的 keyBy 后的聚合操作存在数据倾斜。keyBy 之前的数据直接来自于数据源,一般不会出现数据倾斜,除非数据源中的数据发生了数据倾斜。本小节将从多个角度来解决数据倾斜。
keyBy 后的聚合操作存在数据倾斜
keyBy 之前发生数据倾斜
9.6.4 小结与反思
加入知识星球可以看到上面文章:https://t.zsxq.com/uFEEYzJ
在前一章中讲解了 Flink 监控系统的重要性,这章主要讲解 Flink 作业的性能调优。当作业出现各种各样的问题时,其实这时就体现了前面章节提到的监控的重要性,所以本章的内容也比较依赖于监控系统,然后才能够更好的去排查问题,然后去解决问题。
在本章中讲解的反压问题、并行度设置问题、数据倾斜问题等都是开发作业时要注意的点,本章不仅讲解了这些问题出现后的解决方案,还深入的剖析了这些问题为啥会出现,只有知其原因后,后面开发新的作业时才会去注意这些问题。本章的内容属于高阶玩家要掌握的,希望你也能够好好理解,在你们公司遇到同样问题的时候可以站出来去解决。