Flink window 数据倾斜 解决思路
原文链接:https://blog.****.net/IT_Lee_J_H/article/details/88641894
这里阐述一下Flink中 window间的数据倾斜的解决思路,不做代码展现。
场景:
分项目统计某个时间粒度的 pv 数据
数据情况:
每个项目的数据量不同,某个项目的数据量很大,导致这个项目的窗口中的数据很大,发生倾斜。
解决思路:
思路一:
针对window原始方式中在窗口触发前,是以数据积攒的方式进行的。所以针对这种方式可以在window后跟一个reduce方法,在窗口触发前采用该方法进行聚合操作(类似于MapReduce 中 map端combiner预处理思路)。如使用 flink 的 aggregate 算子,不推荐使用 apply。
思路二:
思路一处理后仍有倾斜问题,或者也可以直接采用思路二进行优化、处理。
大致思路:
将key进行扩展,扩展成自定义的负载数,即,将原始的key封装后新的带负载数的key,进行逻辑处理,然后再对新key的计算
结果进行聚合,聚合成原始逻辑的结果。
具体实现思路:
1.人为查看具体的倾斜的(数据量大的项目码,例如Code1)
2.将原始的数据元组中keyby分组的键进行扩展,扩展指定的负载个数
例如:
优化前:
数据元组:(项目码,1)
如,(code1,1) (code2,1) (code3,1) (code1,1)......
优化后:
数据元组:(项目码-负载标识,1) 如,(code1-0,1)(code1-1,1)(code1-2,1) (code2,1).....
上述的示例,将数据倾斜的流,进行了负载,负载为3(0,1,2),即只对 code1 的数据进行负载重新组合 key。
如图:
扩展Key:
优化前的keyed流:
优化后的Keyed流:
可见,对数据量大的流进行了二次分流,实现了负载,解决了数据倾斜的问题。
3.按照新的组合的key进行keyby,这样,会根据在自定义的负载数,对数据量大的项目(流),进行负载,并进行初步的window
处理(输出的元组格式:(项目码,pv数) 例如:(code1,457343487) ,(code2,45683)......)
优化前:
优化后:
4.步骤3中的窗口结果的key(和目标的key相同)再次进行keyby操作,这一步目的在于将之前负载分散后的结果,做最后的聚
合,组合成目标逻辑的结果。
优化前:
优化后:
这样,window间的数据倾斜问题解决。
以下为优化前后整体的拓扑图
优化前:
优化后: