热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spark优化总结(一)——数据倾斜

文章目录Spark优化总结(一)——数据倾斜1.前言2.数据源倾斜3.数据存储倾斜4.数据处理倾斜4.1过滤导致的数据不均4.2默认值、异常数据等导致的

文章目录

  • Spark优化总结(一)——数据倾斜
    • 1. 前言
    • 2. 数据源倾斜
    • 3. 数据存储倾斜
    • 4. 数据处理倾斜
      • 4.1 过滤导致的数据不均
      • 4.2 默认值、异常数据等导致的不均
      • 4.3 join导致的数据不均
      • 4.4 groupBy导致的数据不均
      • 4.5 key倾斜了,但还必须要该key?


Spark优化总结(一)——数据倾斜

1. 前言


  • 在Spark应用开发过程中,通常大多数性能问题是在数据倾斜点上。针对数据倾斜问题,我们可以按运行状态分出以下几点:
    • 数据源倾斜
    • 存储结果倾斜
    • 数据处理倾斜(问题最多的部分)

2. 数据源倾斜


  • 说明

    • 使用Spark读取数据时,通常我们的数据源也是分布式存储的,这就需要Spark从数据源的各个节点分别读取数据。如果因为某些原因,导致某份数据在存储集群的各个节点分布不均匀,那么读取数据时需要的时间会等于最慢的节点
    • 例如,数据分布在10个节点上,其中一个节点的数据量是其他的节点的5倍
  • 举例:Hive分桶导致的数据倾斜

    • Hive设计表的时候可为表设定分桶,选择一个良好的分布列能够使数据均匀的分布到集群中。
    • 如果分布列选择错误,很可能导致某些节点数据极其多,而其他节点又很少。那么,使用Spark读取Hive表时,就需要等待数据最多的节点执行完毕。
  • 举例:Kafka分区导致的数据倾斜

    • 生产到Kafka某个Topic的数据,可以指定Partition、Key或者默认值,用于决定数据会发送到Topic的那一个分区。
    • 如果生成的Partition、Key不对,那么会导致Topic某些分区数据量远多于其他分区。那么,使用SparkStream(或者StructuredStream)来接取Topic的数据时,会导致Spark某个节点单次接入的数据过多。

3. 数据存储倾斜


  • 说明

    • 通常利用Spark处理完数据后,需要一个集群用于存储数据。一般来说,HDFS、HIVE等集群不会存在存储性能问题。但是,如果因为某些设计原因,会导致待存储的数据其中大部分需要存入存储集群中的某个节点(或访问某个节点),显然Spark需要等待该节点存储完毕才能结束。
  • 举例:Hive分桶、Kafka分区

    • 和数据源倾斜同理
  • 举例:分布式MPP架构数据库

    • 一般来,分布式数据库会有多个主节点用于JDBC/ODBC连接访问。如果用Spark存储时,只设定一个主节点IP,那么可能会导致分布式数据库该节点访问量激增,从而导致存储效率下降。
    • 解决方案:
      • Spark各节点分别随机选择(或者各自指定)数据库主节点IP
      • 使用数据库自带的数据导入工具(一般是批量导入)
    • 另外,即便不是分布式数据库,如果你的数据库只有一个节点可用,同样会造成该问题
  • 举例:HBase的Rowkey设计错误

    • HBase的数据会根据rowkey进行自然排序,排序相近的数据会存储在一个节点。如果同一时间向HBase某个表装入自然顺序相近的数据,会导致Region热点问题。
    • 例如,利用SparkStream实时采集数据装入HBase的某个表,如果将该表的rowkey设计为以时间开头,那么总是会入库自然顺序相近的数据,导致热点问题,最终入库性能下降。
    • 解决方案:
      • 设计不以时间开头的rowkey
      • 如果每次查询是get,能够具体知道rowkey,那么可以将时间的后几位值移到前面来,这样数据入库就随机了
      • 不需要实时入库时,同时数据一般都需要在HIVE备份,那么可以用Spark批量读取数据,repartiton一下,将数据顺序打乱,然后入库HBase

4. 数据处理倾斜


4.1 过滤导致的数据不均


  • 开发时,在处理数据之前提前做好过滤,是一个良好的习惯。但是,过滤条件(例如where、filter)可能会导致部分分区的数据量较少(因为该分区符合过滤条件的数据少),而其他分区数据较多,那么本次Stage执行的时间将取决于最慢的节点(数据最多)。

  • 例如:数据均匀的分布在10个分区,每个节点分区约1000万条。你需要根据某个条件进行过滤数据,然后再执行处理操作。当数据过滤后,可能其中3个分区约有900万条符合条件,其他7个分区约有200万条符合条件。接着继续执行后续逻辑,显然本次Stage需要等数据最多的3个分区执行完才能结束(如果过滤后需要执行的处理逻辑较为花费时间,例如每条数据还需要10秒,那么效果尤为明显)。

  • 解决方案:

    • 使用repartion将数据再次分布均匀。需要注意的是repartion是shuffle操作,网络传输需要消耗时间,如果你的数据倾斜程度不大可以不做。也就是说你需要对比repartion的时间开销与数据倾斜导致的时间开销后,再做决定。
    • 如果直接repartion也倾斜了,那么你需要调用partitionBy()重写一个Patitioner,选择合适的字段来做Shuffle。(没有合适的字段,那就加随机前缀)
    • 关于coalesce,在此几乎没有效果,因为coalesce是合并各自节点本地的分区,并没有解决数据倾斜的问题
  • 简约示意图

    // 数据原状态| node1 | node2 | node3
    count | 10050 | 10002 | 10035↓
    // where/filter 根据条件过滤| node1 | node2 | node3
    count | 5000 | 510 | 490↓
    // 有的节点符合条件的多,有的节点符合条件的少
    // 如果继续进行map类型的处理,node1将远远慢于node2、node3,同时node2、node3还处于空闲状态(浪费)
    // 如果每条数据的处理时间消耗比较大,node1与node2、node3的差距将非常大↓
    // 使用repartition,重新分布| node1 | node2 | node3
    count | 2014 | 1997 | 1989↓
    // 继续进行map类型处理,每个节点的计算资源都利用起来了
    // ……


4.2 默认值、异常数据等导致的不均


  • 开发中遇到数据倾斜,可以优先排查该项。通常一个字段的处理中很可能会给一个默认值(例如0、null、空白字符等)或者一个异常值(例如@#¥%),这都是上游解析的问题导致的。
  • 例如,一个表共1亿条数据,其中一列80%都是默认值字符串“01234”,如果使用该列作为shuffle分区的key,那么会导致数据倾斜。
  • 建议提前统计好默认值或异常值的占比(例如抽样统计),如果不需要为该值的数据,那么提前过滤掉。如果需要,可以尝试加随机前缀(前提是能满足你的业务)。另外,你可以换一种业务的实现方式,想办法选择其他列作为shuffle的分区key。

4.3 join导致的数据不均


  • 进行join时需要选择一个列,如果该的列值倾斜那么join操作也会倾斜。
  • 例如:某批订单信息约1000万条,其中有city字段,其中A、B城市订单较多(各约300万),其他城市订单量较少(都少于50万)。此时需要将一份城市相关的数据与该数据关联,如果选择city字段进行join,会使各城市订单信息分别分布到各个分区节点上。显然A、B城市订单数据各自所在分区节点的数据量较大,需要等待该分区处理完,Stage才算结束。
  • 解决方案:
    • 使用广播进行 map-side join
    • 示例:
      • Spark代码可读性与性能优化——示例五(HashJoin)

4.4 groupBy导致的数据不均


  • 进行groupBy时需要选择一个列,如果该的列值倾斜那么groupBy操作也会倾斜。
  • 示例:同join,如果需要根据城市分组处理,执行groupBy操作后,因为A、B城市所在分区节点的数据量较大,同样需要等待。
  • 解决方案:
    • 想办法使用reduceByKey、aggregateByKey、combineByKey替代
    • 示例:
      • Spark代码可读性与性能优化——示例六(groupBy、reduceByKey、aggregateByKey)
      • Spark代码可读性与性能优化——示例八(一个业务逻辑,多种解决方式)

4.5 key倾斜了,但还必须要该key?


  • 如果你的业务每天经常根据该key进行不同的数据处理的话,那么可以尝试预先处理一次。
  • 提前处理该key生成一份数据,虽然第一次仍然会有倾斜问题,速度较慢,但是后面很多次的业务可以跟新新生成的数据进行处理,不会再有该key倾斜的问题了。

推荐阅读
  • 技术日志:深入探讨Spark Streaming与Spark SQL的融合应用
    技术日志:深入探讨Spark Streaming与Spark SQL的融合应用 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 在编写数据库应用程序时,常常需要用户自己在控制面板中配置ODBC数据源。然而对一般用户而言,配置ODBC数据源的工作是有一定困难的。因此, ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • Flowable 流程图路径与节点展示:已执行节点高亮红色标记,增强可视化效果
    在Flowable流程图中,通常仅显示当前节点,而路径则需自行获取。特别是在多次驳回的情况下,节点可能会出现混乱。本文重点探讨了如何准确地展示流程图效果,包括已结束的流程和正在执行的流程。具体实现方法包括生成带有高亮红色标记的图片,以增强可视化效果,确保用户能够清晰地了解每个节点的状态。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 数据库多表联合查询:内连接与外连接详解
    在数据库的多表查询中,内连接和外连接是两种常用的技术手段。内连接用于检索多个表中相互匹配的记录,即只有当两个表中的记录满足特定的连接条件时,这些记录才会被包含在查询结果中。相比之下,外连接则不仅返回匹配的记录,还可以选择性地返回不匹配的记录,具体取决于左外连接、右外连接或全外连接的选择。本文将详细解析这两种连接方式的使用场景及其语法结构,帮助读者更好地理解和应用多表查询技术。 ... [详细]
  • 计算机视觉领域介绍 | 自然语言驱动的跨模态行人重识别前沿技术综述(上篇)
    本文介绍了计算机视觉领域的最新进展,特别是自然语言驱动的跨模态行人重识别技术。上篇内容详细探讨了该领域的基础理论、关键技术及当前的研究热点,为读者提供了全面的概述。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • 在搭建Hadoop集群以处理大规模数据存储和频繁读取需求的过程中,经常会遇到各种配置难题。本文总结了作者在实际部署中遇到的典型问题,并提供了详细的解决方案,帮助读者避免常见的配置陷阱。通过这些经验分享,希望读者能够更加顺利地完成Hadoop集群的搭建和配置。 ... [详细]
author-avatar
郭红飞2001
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有