代码之家  ›  专栏  ›  技术社区  ›  Go Erlangen

如何通过数据帧操作保留分区

  •  3
  • Go Erlangen  · 技术社区  · 6 年前

    有没有可靠的方法来预测哪些Spark数据帧操作会保留分区,哪些不会?

    如果我采用以下方法,我是否可以期望500个分区的输出由这些相同的字段排列:

    1. 选择()
    2. “field1”和“field2”上的join(),当两个数据帧按上述方式进行分区时

    考虑到我的数据准备的特殊方式,我希望不会发生额外的混乱。然而,我似乎总是以至少几个阶段结束,这些阶段的任务数等于spark.sql.shuffle.partitions. 有什么办法可以避免额外的洗牌吗?

    谢谢

    1 回复  |  直到 6 年前
        1
  •  3
  •   Bartosz Konieczny    4 年前

    这是Spark的一个众所周知的问题。即使您重新分区了数据,Spark也会洗牌数据。

    有什么问题

    重分区确保每个分区包含关于单个列值的数据。

    很好的例子 here

    val people = List(
       (10, "blue"),
       (13, "red"),
       (15, "blue"),
       (99, "red"),
       (67, "blue")
    )
    val peopleDf = people.toDF("age", "color")
    colorDf = peopleDf.repartition($"color")
    
    Partition 00091
    13,red
    99,red
    
    Partition 00168
    10,blue
    15,blue
    67,blue
    

    但是,Spark在后续操作中不记得这些信息。另外,不同分区之间分区的总顺序也不会保持在spark中。i、 Spark知道单个分区有一个分区的数据,但不知道其他分区有同一列的数据。此外,还需要对数据进行排序,以确保不需要无序排列。

    你需要使用火花 扣合特征

    我找到这个了 Wiki 是非常详细的扣功能。

    Bucketing是sparksql中的一种优化技术,它使用bucket和Bucketing列来确定数据分区。

    其动机是通过避免参与连接的表的无序(即交换)来优化连接查询的性能。Bucketing导致更少的交换(以及更多的阶段)。