代码之家  ›  专栏  ›  技术社区  ›  Jiew Meng

斯帕克:再分配和再分配的区别是什么?[复制品]

  •  0
  • Jiew Meng  · 技术社区  · 6 年前

    数据帧之间的区别是什么 repartition() 和数据框架编写器 partitionBy() 方法?

    我希望两者都是用来“基于dataframe列划分数据”的?还是有什么区别?

    0 回复  |  直到 7 年前
        1
  •  23
  •   Mariusz    7 年前

    如果你跑 repartition(COL) 在计算过程中更改分区-您将得到 spark.sql.shuffle.partitions (默认值:200)分区。如果你打电话来 .write 你将得到一个包含许多文件的目录。

    如果你跑 .write.partitionBy(COL) 然后,您将得到尽可能多的目录和列中的唯一值。这将加快进一步的数据读取(如果您按分区列筛选),并节省一些存储空间(分区列从数据文件中删除)。

    更新 :见@conradlee的回答。他不仅详细解释了应用不同方法后目录结构的外观,而且还详细解释了在这两种情况下会产生多少文件。

        2
  •  120
  •   conradlee    7 年前

    注意:我相信接受的答案是不太正确的!我很高兴你问这个问题,因为这些类似命名的函数的行为在重要和意外的方面有所不同,而官方的spark文档中并没有很好的记录。

    接受的答案的第一部分是正确的:调用 df.repartition(COL, numPartitions=k) 将创建一个数据帧 k 使用基于哈希的分区器的分区。 COL 这里定义分区键——它可以是单个列或列列表。基于散列的分区器获取每个输入行的分区键,并将其散列到 K 通过类似于 partition = hash(partitionKey) % k 。这保证了具有相同分区键的所有行最终都位于同一分区中。然而, 来自多个分区键的行也可以在同一分区中结束。 (当分区键之间发生哈希冲突时)和 某些分区可能为空 .

    总而言之 df.重新分区(col,numpartitions=k) 那是

    • 分区不会严格隔离分区键
    • 你的一些 K 分区可能为空,而其他分区可能包含来自多个分区键的行

    行为 df.write.partitionBy 是完全不同的,在某种程度上,许多用户不会预料到。假设您希望对输出文件进行日期分区,并且您的数据跨越7天。我们也假设 df 从10个分区开始。当你奔跑 df.write.partitionBy('day') ,您需要多少输出文件?答案是“视情况而定”。如果启动分区的每个分区 东风 包含每天的数据,那么答案是70。如果每个启动分区 东风 只包含一天的数据,那么答案是10。

    我们如何解释这种行为?当你奔跑 df.write ,中的每个原始分区 东风 是独立写的。也就是说,原来的10个分区中的每个分区都在“day”列上单独分区,并且为每个分区编写一个单独的文件。

    我觉得这种行为很烦人,我希望在编写数据帧时有一种方法来进行全局重新分区。

    推荐文章