Spark--insert overwrite插入目标表慢/读取orc表执行时间比较长解决

博客针对Spark任务中insert overwrite慢和读取orc表执行时间长的问题进行分析。发现分区数少、单个task计算量大等导致任务慢。解决方法包括设置读取ORC表生成split的策略,如根据文件情况选择BI或ETL策略,还可增加spark并行度,此外还提及可拓展到spill溢出问题。

  • 有个任务最近速度突然变的很慢,排查下来发现两个耗时的stage,其中一个比较有代表性(insert overwrite 比较慢),记录一下
    • 27min → 1.9min

一、问题

  • 有个任务insert overwrite 的时候很慢,整整27min。。。。
  • 查看 web ui
    • 分区数很少
    • 执行时间很长

stage:

在这里插入图片描述

stage详细:
在这里插入图片描述

  • 说明该任务每个分区上的input比较大,单个task计算量较大甚至引起spill导致任务执行慢。

二、解决

  • 如果任务读取的源数据是orc文件,建议设置一下参数,重试任务
    • 设置参数hive.exec.orc.split.strategy
      • 参数控制在读取ORC表时生成split的策略:
      • BI策略以文件为粒度进行split划分;
        • 由于读orc文件时默认按文件划分task(BI模式), 有数据倾斜的表(这里的数据倾斜指大量stripe存储于少数文件中)的情况并发可能不够, 影响执行效率. 可以改成ETL模式
      • ETL策略会将文件进行切分,多个stripe组成一个split;
        • 对于一些较大的ORC表,可能其footer(用于描述整个文件的基本信息、表结构信息、行数、各个字段的统计信息以及各个Stripe的信息)较大,ETL策略可能会导致其从hdfs拉取大量的数据来切分split,甚至会导致driver端OOM,因此这类表的读取建议使用BI策略。
      • HYBRID策略当文件的平均大小大于hadoop最大split值(默认256M)时使用ETL策略,否则使用BI策略。
    • spark.sql.files.maxPartitionBytes=128M是平台默认值,可适当减小该值
      • 增加spark的并行度
set hive.exec.orc.split.strategy=ETL;
set spark.sql.files.maxPartitionBytes=32M;

三、查看结果

在这里插入图片描述

在这里插入图片描述

四、拓展

  • 这个case 其实还可以拓展到splill溢出的问题
  • stage发生spill不是失败,只是task想要的内存量比较大,由于内存不足发生写磁盘,故发生spill任务一定会变慢。
--conf spark.executor.memory=32g
--conf spark.executor.cores=4
Hive中ORC格式的是支持静态数据插入的,但需要满足一定的条件和配置。在某些情况下,例如在使用Spark读取Hive中ORC格式的时,可能会遇到`NullPointerException`等异常,但这并不意味着ORC格式本身不支持静态插入操作。通常,这类问题可能与Hive和Spark之间的兼容性、的分区设置或数据格式配置有关[^1]。 ### Hive ORC格式支持静态插入的条件 1. **启用静态分区插入模式** Hive在较新的版本中默认是关闭静态分区插入功能的,因此需要手动开启。可以通过以下HiveQL语句设置: ```sql SET hive.mapred.mode = nonstrict; ``` 或者在插入数据前执行: ```sql SET hive.exec.dynamic.partition.mode = nonstrict; ``` 2. **确保分区字段值匹配** 在进行静态分区插入时,必须在`INSERT OVERWRITE`语句中明确指定分区字段及其值,例如: ```sql INSERT OVERWRITE TABLE pro60050.browse_wxapp_page_dt_partition PARTITION (dt=20200227) SELECT ... FROM hivedb.hiveTableName WHERE dt=20200227 AND brandId IN (253); ``` 3. **兼容性问题处理** 如果使用Spark访问Hive ORC时遇到问题,建议检查Spark与Hive版本之间的兼容性。某些旧版本的Spark可能对Hive元存储或ORC格式的支持存在限制,可以通过升级Spark或Hive版本来解决此类问题[^1]。 4. **数据格式一致性** 确保插入的数据格式与ORC定义的字段类型一致,包括字段数量、顺序以及数据类型。如果字段不匹配,可能会导致插入失败或运行时异常。 ### 无法插入时的解决方法 - **检查Hive版本与配置** 确认Hive版本是否支持静态分区插入,并检查`hive-site.xml`中的配置是否正确设置。 - **使用动态分区插入替代** 如果静态分区插入存在困难,可以尝试使用动态分区插入,通过在`SELECT`语句中包含分区字段来实现: ```sql INSERT OVERWRITE TABLE pro60050.browse_wxapp_page_dt_partition PARTITION (dt) SELECT ..., dt FROM hivedb.hiveTableName WHERE dt=20200227 AND brandId IN (253); ``` - **验证ORC文件结构** 如果数据是通过其他方式生成的ORC文件,需要确保文件结构与Hive定义一致。可以使用Hive的`LOAD DATA`命令加载数据,或者通过`ALTER TABLE RECOVER PARTITIONS`修复分区。 - **日志与异常分析** 如果遇到`NullPointerException`等异常,应仔细查看Hive和Spark的日志,确认问题根源。通常这类问题可能与元数据不一致、分区未正确注册或Spark配置不当有关[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值