Spark 中的分区与数据湖中的分区

Partitions in Spark Vs Partitions in a Data Lake

将文件写入数据湖时,特别是通过 Databricks,我们可以选择指定分区列。这将根据数据集该列中可用的值将数据保存在单独的文件夹(分区)中。

同时,当我们谈论 Spark 优化时,我们谈论的是数据分区。

这两者有什么区别?他们之间有关系吗?

据我了解,将分布式文件系统中的数据分区保存在我们只想读入特定部分数据(当然基于分区列)时会有所帮助。例如,如果我们按颜色分区并且我们只对 'red' 条记录感兴趣,我们可以只读入该分区而忽略其余部分。这会在读取数据时带来一定程度的优化。

那么,为了让Spark进行并行处理,这个'red'分区(来自文件系统)会根据集群中可用的核数划分为分区(Spark)吗?

这是正确的吗? Spark 是如何决定分区数量的?这个数字是否总是等于集群中的核心数?

重新分区的思路是什么?我相信这涉及使用 coalesce()repartition() 函数。是什么导致Spark重新分区数据?

保存到分区(文件夹)和 spark 分区都是分区数据,但相似之处仅此而已。

如果您经常通过过滤特定(文件夹)列来查询数据,那么将数据保存在分区(文件夹)中是有意义的。如果您要跨列汇总数据,那么实际上最好不要按列对数据进行分区(文件夹)。

Spark 分区通常是数据的内部决策。换句话说:Spark 分区是数据中并行性的度量。理想情况下,您执行的最昂贵的操作平均划分您的分区,以便每个核心同时忙碌并且没有执行程序滞后。 (通常是倾斜的迹象)。

200 是 spark 中的默认分区数。理想情况下,您希望按照我所说的那样将其设置为将处理您的数据的核心数量的倍数。一般来说,在需要调整性能之前不要乱用分区的数量。一般来说,与调整分区数量相比,通过重新访问您使用的算法和 spark 功能可以完成更多调整。 (但在某些边缘情况下,您确实可以获得更好的性能,例如偏斜。)如果每一秒都很重要..那么是的,也许在您已经调整了所有其他内容之后查看分区。

可以随时进行重新分区以加快计算速度。您可以指定一个更小的数字 (repartion/coalesce),它会折叠您的分区。(使用散列函数进行合并)您可以这样做以将一个文件写入磁盘,或者压缩您的数据以最大化吞吐量。 (在我们不生活的理想世界中,您希望所有分区都小于您所在文件系统的块大小。这意味着您正在最大化块读取。在 hdfs 中,这通常是 128M,但您可以根据您的需要进行调整。)

您可能希望增加分区数量(使用重新分区)或以有利的方式重新分配数据。 repartition 确实接受一个自定义函数,您可以使用它来指定数据的分区方式。您可能会使用它来绕过数据倾斜,但现在 spark will do that for you if you tell it to. As I discussed above you may wish to grow/shrink the number of partitions to match a mutliple of your cores. You likely want to use spark.sql.shuffle.partitions by the way that is briefly explained .