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%左右,效果相当明显。另外,看到有文章建议和解释并行度设置的规则,还可以尝试优化。