我对以下方法中numPartitions
参数的行为感到困惑:
DataFrameReader.jdbc
Dataset.repartition
DataFrameReader.jdbc
的{{3}}对numPartitions
参数
numPartitions : 分区数量。这与lowerBound(包含),upperBound(不包括)一起形成分区步骤,用于生成的WHERE子句表达式,用于均匀地分割列columnName。
Dataset.repartition
的{{3}}说
返回一个具有完全
numPartitions
分区的新数据集。
我目前的理解:
numPartition
方法中的DataFrameReader.jdbc
参数在从数据库中读取数据时控制并行度 numPartition
中的Dataset.repartition
参数控制将DataFrame
写入磁盘时生成的输出文件数 我的问题:
DataFrame
读取DataFrameReader.jdbc
,然后将其写入磁盘(不调用repartition
方法),那么输出中的文件数量是否仍然与输出数量相同?我在调用DataFrame
之后写了repartition
到磁盘上了吗?repartition
方法(带DataFrame
参数)读取的DataFrameReader.jdbc
上调用numPartitions
方法是多余的吗?numPartitions
方法的DataFrameReader.jdbc
参数称为' parallelism' ?答案 0 :(得分:1)
简短回答:两种方法中numPartitions
参数的行为(几乎)无差异
<强> read.jdbc(..numPartitions..)
强>
此处,numPartitions
参数控制:
MySQL
(或任何其他RDBM
)用于读取数据到{{1 }}。DataFrame
上的所有后续操作的DataFrame
方法 <强> repartition
强>
此处repartition(..numPartitions..)
参数控制执行<{1}}的任何操作时出现的并行度,包括写作到磁盘。
所以基本上使用numPartitions
方法在阅读DataFrame
表时获得的DataFrame
行为相同(在执行的操作中表现出相同的并行度)好像它是读没有并行并且之后调用了MySQL
方法(显然具有相同的值spark.read.jdbc(..numPartitions..)
)
回答确切的问题:
如果我通过DataFrameReader.jdbc读取DataFrame然后将其写入磁盘 (没有调用重新分区方法),那么仍然会有 输出中的很多文件,因为我会写出来的 在调用重新分区后,DataFrame到磁盘?
是
假设 read 任务已经并行化,方法是提供适当的参数(repartition(..numPartitions..)
,numPartitions
,columnName
&amp; {所有lowerBound
上的所有操作(包括写入)将并行执行。在此处引用official docs:
numPartitions:表读取和写入中可用于并行度的最大分区数。这还确定了最大并发JDBC连接数。如果要写入的分区数超过此限制,我们通过在写入之前调用coalesce(numPartitions)将其减少到此限制。
是:那么在使用DataFrameReader.jdbc方法(使用numPartitions参数)读取的DataFrame上调用重新分区方法是多余的吗?
是
除非您调用upperBound
方法的其他变体(采用numPartitions
param的方法),否则在DataFrame
{同一repartition
上调用columnExprs
})参数是多余的。但是,我不确定在已经并行化的 repartition
上强制执行并行度是否也会调用 shuffling DataFrame
之间的数据不必要。我遇到它后会更新答案。