Flink教程-keyby 窗口数据倾斜的优化

在大数据处理领域,数据倾斜是一个非常常见的问题,今天我们就简单讲讲在flink中如何处理流式数据倾斜问题。

我们先来看一个可能产生数据倾斜的sql.

select TUMBLE_END(proc_time, INTERVAL '1' MINUTE) as winEnd,plat,count(*) as pv  from source_kafka_table 
group by TUMBLE(proc_time, INTERVAL '1' MINUTE) ,plat

在这个sql里,我们统计一个网站各个端的每分钟的pv,从kafka消费过来的数据首先会按照端进行分组,然后执行聚合函数count来进行pv的计算。如果某一个端产生的数据特别大,比如我们的微信小程序端产生数据远远大于其他app端的数据,那么把这些数据分组到某一个算子之后,由于这个算子的处理速度跟不上,就会产生数据倾斜。

查看flink的ui,会看到如下的场景。

对于这种简单的数据倾斜,我们可以通过对分组的key加上随机数,再次打散,分别计算打散后不同的分组的pv数,然后在最外层再包一层,把打散的数据再次聚合,这样就解决了数据倾斜的问题。

优化后的sql如下:

select winEnd,split_index(plat1,'_',0) as plat2,sum(pv) from (

  select TUMBLE_END(proc_time, INTERVAL '1' MINUTE) as winEnd,plat1,count(*) as pv from (

    -- 最内层,将分组的key,也就是plat加上一个随机数打散
    select plat || '_' || cast(cast(RAND()*100 as int) as string) as plat1 ,proc_time from source_kafka_table 

) group by TUMBLE(proc_time, INTERVAL '1' MINUTE), plat1

) group by winEnd,split_index(plat1,'_',0)

在这个sql的最内层,将分组的key,也就是plat加上一个随机数打散,然后求打散后的各个分组(也就是sql中的plat1)的pv值,然后最外层,将各个打散的pv求和。

注意:最内层的sql,给分组的key添加的随机数,范围不能太大,也不能太小,太大的话,分的组太多,增加checkpoint的压力,太小的话,起不到打散的作用。在我的测试中,一天大概十几亿的数据量,5个并行度,随机数的范围在100范围内,就可以正常处理了。

修改后我们看到各个子任务的数据基本均匀了。

这种方法,令程序的每秒总吞吐量下降了不少,吞吐量下降可是个沉痛的代价呀,你的程序会慢好多。之前的4号并行度的每秒吞吐量就4千万QPS,之后10个并行度的总QPS才1千5百万左右。

我觉得还不如任期数据倾斜。或者你在kafka producer往topic写数据的时候,给message的key加上个"数字-"的前缀,即加盐打散的事情,让producer来做

在生产端最好,不过有时候是生产方在写入的时候是按照自己的规则写入的,可能没有数据倾斜,但是有很多人消费,每个人消费的时候逻辑处理是不一样的,可能某一种消费规则就会造成数据倾斜。

如果是任其倾斜,木桶原理,消费慢的算子会拖慢整体的进度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值