博客
关于我
Spark shuffle调优之 合并map端输出 基于HashShuffle
阅读量:638 次
发布时间:2019-03-14

本文共 2072 字,大约阅读时间需要 6 分钟。

Spark Shuffle 优化技术说明

Spark Shuffle 是 Spark 中处理大数据时的关键机制,主要用于在 shuffle stage(混合阶段)中高效地分区和处理数据。本文将详细阐述 Shuffle 的原理、常见问题及优化方法,帮助开发者理解并优化其Spark应用的性能表现。


Shuffle 机制概述

Spark 提供两种 Shuffle 类型:HashShuffleSortShuffle。默认的分区器在 Spark 1.2 之前是 HashPartitioner,而从 1.2 版本起,默认使用 RangePartitioner

  • HashShuffle:采用哈希分区器,将数据按照哈希值随机分布到不同的分区中。
  • SortShuffle:按键的顺序进行分区,类似于文本处理中的字典序排列。

使用哈希分区器的 HashShuffle 是早期的默认分区器,但随着大规模数据处理需求的增加,哈希分区带来的文件数量爆炸性增长已成为性能瓶颈。因此,后续版本推荐或改用 SortShuffle,以提高性能和可扩展性。


HashShuffle 的工作原理

HashShuffle 的工作流程包括以下几个关键步骤:

  • Buffer 写入

    • 每个 map task 将计算结果写入内存缓冲区(buffer),每个 buffer 的默认大小为 32 KB。
    • buffer 作为临时存储,用于缓存数据写入磁盘小文件的频繁操作。
  • 小文件生成

    • buffer 确定完整后,会生成对应的磁盘小文件。
    • 这些小文件将根据默认分区器(HashPartitioner)的 key hash 值进行分类。
  • ReduceTask 调用

    • Reduce task 会在下一个阶段拉取所需的磁盘小文件,以便汇总并处理相关数据。
  • 虽然这种机制设计初衷合理,但在大规模任务处理下,会面临以下问题:

    • 文件数量爆炸:Map task 数量与 Reduce task 数量的乘积直接决定小文件总数,容易导致磁盘资源耗尽。
    • 频繁的 IO 操作:大量小文件的写入和读取耗费大量 I/O 操作,增加了硬盘负载。
    • GC 启particles:内存中存储过多的缓冲对象会触发频繁的垃圾回收,导致内存不足时可能导致 OOM 错误。
    • 网络通信压力:Reduce task 需要从多个节点拉取小文件,增加了网络 I/O �态。

    这种情况下,特别是在大规模 Spark 作业中,文件数量可达百万级别,直接影响性能表现。


    HashShuffle 合并机制的引入

    为了应对文件数量爆炸的问题,Spark 引入了 map 端输出文件合并机制,通过以下方式实现优化:

    配置参数启用

    spark.shuffle.consolidateFiles = "true"

    启用该配置后,合并机制将确保多个短小文件合并成少量的大文件,具体表现包括:

  • 减少磁盘小文件数量

    • 在生产环境下,原有的 100 万小文件可减少至 20 万,显著降低磁盘占用。
  • 优化 Reduce 操作

    • Reduce task 在合并后只需处理合并后的少量文件,减少了网络传输的负担。
    • 合并后的文件数仅需根据 executor 核心数计算,而非 Map task 数量。
  • 并行优化效果显著

    • 合并机制避免了多批 task 同时运行时无法复用的文件惯例问题。
    • 实际应用中,作业完成时间减少 30%-50%,提升资源利用率。

  • 滑块合并的注意事项

    在实际应用中,合并机制的效果依赖于以下因素:

  • 任务分布

    • 多批次任务运行时,合并机制效果最佳。
    • 同时运行多批任务时,可能需要额外配置。
  • 任务密度

    • 任务密度高时(如每个 executor 多运行 task),合并效应更明显。
  • Executor 资源

    • 每个 executor 的核心数目直接影响合并效果,执行核心越多,合并能力越强。
  • 应用架构

    • 使用夹带裂解(spark.caction杀)或其他优化架构方案时,需谨慎调整。

  • 实际应用中的性能改善

    以生产环境配置为例:

    • 节点数:100 个 executor,每个运行 2 核心。
    • 总 Task 数:1000 个 executor,每个平均 10 个 task。

    启用合并机制前后,磁盘小文件数量的对比如下:

    • 合并前:100 × 2 × 10 = 2000 个 file(每个 executor)。
    • 合并后:100 × 2 = 200 个 file(每个 executor)。

    结果显示,磁盘小文件数量减少 5 倍(从 20 万减少至 4 万)。这显著优化了 I/O 操作和网络传输负担,进而提升 Spark 作业性能。


    总结与建议

    HashShuffle 的默认机制在大规模数据处理中表现欠佳,主要因为磁盘小文件数量爆炸,带来性能瓶颈。通过启用合并机制可有效解决这一问题,显著降低磁盘占用和网络压力,提升 Spark 作业的整体性能。

    在实践中,开发者应根据具体场景合理调整配置参数,并关注任务分布和资源分配策略,以发挥合并机制的最佳效果。

    转载地址:http://bhblz.baihongyu.com/

    你可能感兴趣的文章
    NT symbols are incorrect, please fix symbols
    查看>>
    ntelliJ IDEA 报错:找不到包或者找不到符号
    查看>>
    NTFS文件权限管理实战
    查看>>
    ntko web firefox跨浏览器插件_深度比较:2019年6个最好的跨浏览器测试工具
    查看>>
    ntko文件存取错误_苹果推送 macOS 10.15.4:iCloud 云盘文件夹共享终于来了
    查看>>
    ntp server 用法小结
    查看>>
    ntpdate 通过外网同步时间
    查看>>
    ntpdate同步配置文件调整详解
    查看>>
    NTPD使用/etc/ntp.conf配置时钟同步详解
    查看>>
    NTP及Chrony时间同步服务设置
    查看>>
    NTP服务器
    查看>>
    NTP配置
    查看>>
    NUC1077 Humble Numbers【数学计算+打表】
    查看>>
    NuGet Gallery 开源项目快速入门指南
    查看>>
    NuGet(微软.NET开发平台的软件包管理工具)在VisualStudio中的安装的使用
    查看>>
    nuget.org 无法加载源 https://api.nuget.org/v3/index.json 的服务索引
    查看>>
    Nuget~管理自己的包包
    查看>>
    NuGet学习笔记001---了解使用NuGet给net快速获取引用
    查看>>
    nullnullHuge Pages
    查看>>
    NullPointerException Cannot invoke setSkipOutputConversion(boolean) because functionToInvoke is null
    查看>>