数据倾斜专题

数据倾斜

一 数据倾斜的具体表现

1.1 hadoop

1.1.1 hadoop产生数据倾斜的现象

当我们看任务进度长时间维持在99%,这里如果详细的看日志或者和监控界面的话会发现:

  • 有一个多几个reduce卡住,一直不结束
  • 各种container报错OOM
  • 读写的数据量极大,至少远远超过其它正常的reduce
  • 伴随着数据倾斜,会出现任务被kill等各种诡异的表现
1.1.2 定位数据倾斜

​ 可以直接同Yarn的8088监控页面查看

1.2 hive

1.2.1 hive产生数据倾斜的情况

​ 出现数据倾斜的情况:

  1. join时候使用不同数据类型连接

    1. hive中过多的null进行join会产生数据倾斜
1.2.2 定位数据倾斜

​ 跟hadoop的MR相同

1.3 spark

1.3.1 当发现如下现象时,十有八九是发生数据倾斜了:
  • 绝大多数 task 执行得都非常快,但个别 task 执行极慢,整体任务卡在某个阶段不能结束。
  • 原本能够正常执行的 Spark 作业,某天突然报出 OOM(内存溢出)异常,观察异常栈,是我们写的业务代码造成的。这种情况比较少见。

TIPS

在 Spark streaming 程序中,数据倾斜更容易出现,特别是在程序中包含一些类似 sql 的 join、group 这种操作的时候。因为 Spark Streaming 程序在运行的时候,我们一般不会分配特别多的内存,因此一旦在这个过程中出现一些数据倾斜,就十分容易造成 OOM。

1.3.2 如何定位数据倾斜
  1. 通过Spark Web UI

    通过 Spark Web UI 来查看当前运行的 stage 各个 task 分配的数据量(Shuffle Read Size/Records),从而进一步确定是不是 task 分配的数据不均匀导致了数据倾斜。

    知道数据倾斜发生在哪一个 stage 之后,接着我们就需要根据 stage 划分原理,推算出来发生倾斜的那个 stage 对应代码中的哪一部分,这部分代码中肯定会有一个 shuffle 类算子。可以通过 countByKey 查看各个 key 的分布。

    TIPS

    数据倾斜只会发生在 shuffle 过程中。这里给大家罗列一些常用的并且可能会触发 shuffle 操作的算子: distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup、repartition 等。出现数据倾斜时,可能就是你的代码中使用了这些算子中的某一个所导致的。

  2. 通过key抽样统计

    也可以通过抽样统计 key 的出现次数验证。

    由于数据量巨大,可以采用抽样的方式,对数据进行抽样,统计出现的次数,根据出现次数大小排序取出前几个:

    df.select("key").sample(false, 0.1)           // 数据采样
        .(k => (k, 1)).reduceBykey(_ + _)         // 统计 key 出现的次数
        .map(k => (k._2, k._1)).sortByKey(false)  // 根据 key 出现次数进行排序
        .take(10)                                 // 取前 10 个。
    

    如果发现多数数据分布都较为平均,而个别数据比其他数据大上若干个数量级,则说明发生了数据倾斜。

1.4 flink

1.4.1 数据倾斜对flink的影响
(1)单点问题

​ 数据集中在某些分区上(Subtask),导致数据严重不平衡。

(2)GC 频繁

​ 过多的数据集中在某些 JVM(TaskManager),使得JVM 的内存资源短缺,导致频繁 GC。

(3)吞吐下降、延迟增大

​ 数据单点和频繁 GC 导致吞吐下降、延迟增大。

(4)系统崩溃

​ 严重情况下,过长的 GC 导致 TaskManager 失联,系统崩溃。

1.4.2 flink如何定位数据倾斜
  1. 通过反压判断,Flink Web UI 自带的反压监控(直接方式),一旦哪个地方出现反压就可以定位到哪里产生了数据倾斜
  2. Flink Web UI 自带Subtask 接收和发送的数据量。当 Subtasks 之间处理的数据量有较大的差距,则该 Subtask 出现数据倾斜。

二 数据倾斜的解决办法

2.1 解决数据倾斜的思路

  1. 业务逻辑, 比如出现城市热点数据可以单独拿出来处理,另外平均的一起处理
  2. 程序层面, 在shuffle过程或者算子过程中
  3. 调参方面, Hadoop和Spark都自带了很多的参数和机制来调节数据倾斜,合理利用它们就能解决大部分问题。

2.2 hadoop解决数据倾斜的方法

  1. 大小表join的时候,将reducejoin换位mapjoin,在map阶段将小表存到内存中,可以避免数据倾斜(程序层面)

    适用场景: MR处理多个结构化数据join的时候产生的数据结构
    
  2. 对于数据量过大的数据,单独MR(在不影响结果前提下)(业务逻辑)

    适用场景: 针对出现热点问题统计的情况(不适合计算粘性太强的计算)
    
  3. 在map阶段结束后先进行combine,这个只能减缓网络传输,IO的压力(程序层面)

    适用场景: 同样适用于计算粘性不强的计算
    
  4. 局部聚合加上全局聚合:

    第一次mr阶段对那些导致了数据倾斜的key加上随机的前缀,然后第二次的MR讲这些随机的key再次聚合(效率比较低,受业务限制)(程序方面)

    适用场景: 大部分场景,尤其是复杂计算
    缺点: 两个MR浪费时间和资源
    
  5. 实现自定义的分区,避免数据倾斜

    适用场景: 根据业务自定义分区可以解决大部分问题
    
  6. 在不影响的业务的前提下,增加分区的数量,也就是增加reduce个数(参数方面)

    适用场景: 适用计算结果不依赖分区的结果,适用默认分区HashPartitioner
    

2.3 hive解决数据倾斜的方法

  1. hive支持针对数据倾斜的处理的参数配置(参数方面)

     hive.groupby.skewindata=true
    

    这种方法类似于MR的局部聚合加上全局聚合

    适用场景: 大部分场景
    缺点: 两个MR,浪费时间和资源
    
  2. 不使用left join改用left semi jioin的使用,前者会把所有的数据遍历,后者会根据匹配不上的值跳过 (程序层面)

    适用场景: sparkSQL需要join的时候
    
  3. 设置多个reduce个数(参数方面)

    适用场景: 适用计算结果不依赖分区的结果,适用默认分区HashPartitioner
    
  4. 针对hive产生数据倾斜的情况作出优化:

    1. 针对数据类型不一致时先检验数据结构或者全部转换为字符串比较
    2. 对于null值较多的情况,可以对null进行添加随机后缀的操作来避免null分区过多

2.4 spark解决数据倾斜的方法

  1. 对于异常数据的清理

  2. 提高shuffle并行度(只能解决hash冲突带来的数据倾斜,因为spark默认的分区器是HashPartitioner)

    适用场景: hash冲突将不同的key传入一个task
    
  3. 自定义分区器

    适用场景: 大部分场景
    
  4. 使用mapjoin(通过广播变量实现)

    适用场景: sparkSQL大小表
    
  5. 针对sparkSQL有一个分开join然后union(一表有倾斜,一表没有,将倾斜部分key加前缀然后再join,最后除掉前缀之后union)

    适用场景: 一表有倾斜,一表没有,两表都不小
    
  6. 大表加盐,小表扩大N倍

    适用场景: 大小表
    
  7. 加盐局部聚合+去盐全局聚合(两次MR)

    适用场景: 大部分场景
    缺点: 两次MR,浪费时间和资源
    

2.5 flink解决数据倾斜的方法

  1. 调整并行度

    适用场景: 数据源 source 消费不均匀
    
  2. key加盐

    适用场景: key 分布不均匀的无统计场景
    
  3. 两阶段聚合:加盐局部聚合,去盐全局聚合

    适用场景: key 分布不均匀的统计场景
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值