Flink调优:数据倾斜优化

1. 定义

当进行聚合运算时(Group By/KeyBy + Agg),如果聚合所使用的key存在热点,则会导致数据倾斜。如统计某日各个省份的车流量,则负责运算北京、上海等一线城市的count subtask节点则会成为热点,处理数据的压力会比较大。

1.1 危害
1.1.1 任务卡死

keyBy 或 rebalance 下游的算子,如果单个 subtask 存在热点并完全卡死,会把整个 Flink 任务卡死。看如下示例:
如下图所示,上游每个 Subtask 中会有 3 个 resultSubPartition,连接下游算子的 3 个 subtask。下游每个 subtask 会有 2 个 InputChannel,连接上游算子的 2 个 subtask。Local BufferPool为subtask中的ResultSubpartition/InputChannel所共用,在正常运行过程中如果没有反压,所有的 buffer pool 是用不完的。

在这里插入图片描述

图1

一旦subtask B0变成热点,则会引起反压,依次产生如下问题:

1、Subtask B0 内的 A0 和 A1 两个 InputChannel 会被占满;Subtask B0 公共的 BufferPool 中可申请到的空间也被占满

2、Subtask A0 和 A1 的 B0 ResultSubPartition 被占满;Subtask A0 和 A1 公共的 BufferPool 中可申请到的空间也被占满

3、如图2所示,Subtask A0 的主线程会从上游读取数据消费,按照数据的 KeyBy 规则,将数据发送到 B0、B1、B2 三个 ResultSubpartition 中;可以看到,如果 B0 这个ResultSubpartition占满了,且 B0 在公共的 Local BufferPool 中可申请到的空间也被占满。现在有一条数据被keyby后发往B0,但是现在 B0 这个ResultSubpartition 没有空间了,所以主线程就会卡在申请 buffer 上,直到可以再申请到 buffer。
Subtask A0 的主线程被卡住,则不会往下游的任何subtask发送数据了,如图1所示,下游的Subtask B1和Subtask B2不再接收新数据。整个任务处于瘫痪状态。

在这里插入图片描述

图2

Flink的数据传播机制参考下图:
在这里插入图片描述

图3
1.1.2 checkpoint时间变长

checkpoint barrier也是一种特殊的数据,如果整个任务中各个可用buffer变少,则checkpoint barrier的传输也会因为找不到可用buffer而降低速度;由于checkpoint barrier的对齐机制,会造成当前checkpoint的barrier迟迟无法对齐,进而超时

1.1.3 state变大

对于有两个以上输入管道的 Operator,存在checkpoint barrier对齐机制,接受到较快的输入管道的 barrier 后,它后面数据会被缓存起来但不处理,直到较慢的输入管道的 barrier 也到达,这些被缓存的数据会被放到state 里面,导致 checkpoint 变大

2. 解决办法

2.1 修改分区策略
2.1.1 目标

让不需要shuffle的两个算子间进行shuffle,打乱数据,从而避免数据倾斜

2.1.2 手段

在Flink任务提交后,经常可以看到web ui中的一些算子之间采用的分区策略是forward,在该分区策略下很可能会存在数据倾斜现象。如以下情况:
某kafka topic统计每个省份的车次,针对每个省份都有一个partition,共计36个partition,同时设有36个source算子,36个flatmap算子。由于source和flatmap满足one-to-one关系,且并行度相同,则Flink默认会采用forward这个分区策略来关联source和flatmap这两个算子。
Flink默认设置forward分区策略有两个条件:

  1. 两个算子满足one-to-one关系
  2. 两个算子并行度相同

此时,北京和上海对应的flatmap算子必然会出现热点数据,由于sourceflatmap算子之间并不需要有特定的对应关系,因此可以采用不同的分区策略来将数据打乱,让不同省份的车流数据落到所有的flatmap算子,消除数据倾斜。
因此,我们只需要破坏forward分区策略的条件即可

  1. 修改两个算子的并行度
  2. 强行设定分区策略,代码如下:
dataStream.rebalance(
  • 8
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值