1 问题描述

1.1 业务描述

        最近上线一个任务,拓扑大概是这样:

  • 从几个kafka集群读取数据做简单处理加工,union成一个数据流
  • 读取并广播配置信息
  • 将前两者数据流connect后过滤一部分数据,并再加工处理
  • 数据流根据三个类型的key进行keyby和窗口操作
  • 最后将结果sink到kafka

1.2 资源配置

  • CPU核心数据:10核
  • 单核内存:4g
  • taskmanager.numberOfTaskSlots:4
  • 全局并行度:40

1.3 问题现象

        kafka消息在白天1000-2000的时候,taskmanager的cpu使用率就达到45-50%。如果遇上晚上数据高峰期或者赛事期间,数据量暴涨,很容易成为瓶颈。

2 问题定位

2.1 业务逻辑优化

        反复检查和优化业务逻辑,窗口操作并不太复杂,数据量大时,state可能大点,但估算后应该不是瓶颈,几个细节优化效果并不明显。

2.2 并行度优化

        凭经验,当前的资源不是问题,cpu和内存都已经足够,问题可能是并行度设置。刚开始调大并行度,slot数据从4改成8,全局并行度从40改成80,重启任务后,cpu资源并没有下降。

        查看官方文档和一些网上资料,涉及key state的情形,可能会因并行度太大反而性能降低;另外并行度的值也建议成2的幂次方。

        摘自flink官方文档

设置最大并行度 #

最大并行度可以在所有设置并行度的地方进行设定(客户端和系统层次除外)。与调用 setParallelism() 方法修改并行度相似,你可以通过调用 setMaxParallelism() 方法来设定最大并行度。

默认的最大并行度等于将 operatorParallelism + (operatorParallelism / 2) 值四舍五入到大于等于该值的一个整型值,并且这个整型值是 2 的幂次方,注意默认最大并行度下限为 128,上限为 32768

注意 为最大并行度设置一个非常大的值将会降低性能,因为一些 state backends 需要维持内部的数据结构,而这些数据结构将会随着 key-groups 的数目而扩张(key-group 是状态重新分配的最小单元)。

       保证足够的并行度,并行度不是越大越好,太多会加重数据在多个solt/task manager之间数据传输压力,包括序列化和反序列化带来的压力。

        尝试:先调小并行度:将slot从4改成2,全局并行度从40改成20,重启任务,发现taskmanager的cpu使用率从45-50%降到15%左右,效果相当明显。另外,看到有文章建议和解释并行度设置的规则,还可以尝试优化。