【问题标题】:How to know when to repartition/coalesce RDD with unbalanced partitions (without shuffling possibly)?如何知道何时重新分区/合并具有不平衡分区的 RDD(可能没有改组)?
【发布时间】:2015-11-03 17:05:29
【问题描述】:

我正在为我的 spark 作业从 s3 加载数以万计的 gzip 压缩文件。这导致一些分区非常小(10 条记录)和一些非常大(10000 条记录)。分区的大小在节点之间分布得很好,因此每个执行程序似乎都在处理相同数量的数据。所以我不确定我是否有问题。

我如何知道是否值得重新分区或合并 RDD?这些中的任何一个都能够在不改组数据的情况下平衡分区吗?此外,RDD 不会被重用,只是映射然后加入另一个 RDD。

【问题讨论】:

    标签: apache-spark


    【解决方案1】:

    有趣的问题。 With respect to coalescing versus repartitioning,合并肯定会更好,因为它不会触发完全洗牌。通常,当您跨分区有稀疏数据时(例如,在过滤器之后),建议使用合并。我认为这是一个类似的场景,但直接来自初始负载。但是,我真的认为合并对你来说可能是值得的,因为你在初始加载后对 RDD 做了什么。

    当您将 join 应用到加载的 RDD 时数据被洗牌时,Spark 会咨询洗牌管理器以查看它应该使用哪种洗牌实现(通过 spark.shuffle.manager 配置)。随机播放管理器有两种实现:hash(版本 sort(默认值 >= 1.2.0)。

    如果使用hash 实现,每个输入分区将创建输出文件以发送到将发生连接的相应reducer。这可能会造成大量文件爆炸,可以通过将spark.shuffle.consolidateFiles 设置为 true 来缓解这种情况,但如果有很多分区作为输入,最终会导致连接速度非常慢。如果使用这种实现,合并绝对是值得的,因为大量的输入分区会产生大量需要减少的文件。

    如果使用sort 实现,每个分区只有一个输出文件(哇!),并且该文件被索引,这样reducer 可以从它们各自的索引中获取它们的键。但是,对于许多输入分区,Spark 仍将读取所有输入分区以收集每个可能的键。如果使用此实现,则合并可能仍然值得,因为将这种查找和读取应用于每个分区也可能代价高昂。

    如果您最终使用了合并,那么您可能需要调整要合并到的分区数量,因为合并将是您执行计划中的一个步骤。但是,此步骤可能会为您节省非常昂贵的加入。另外,作为旁注,this post 对解释 shuffle 背后的实现非常有帮助。

    【讨论】:

    • 在两个参与join的大RDD中调用coalesce可以减少shuffle的数量吗?
    猜你喜欢
    • 2017-05-03
    • 2019-09-12
    • 1970-01-01
    • 2016-02-20
    • 2015-11-25
    • 2018-01-26
    • 1970-01-01
    • 2018-02-16
    相关资源
    最近更新 更多