Spark:read.jdbc(..numPartitions..) 和 repartition(..numPartitions..) 中 numPartitions 的区别

y2k*_*ham 7 dataframe apache-spark spark-dataframe spark-jdbc

numPartitions对以下方法中参数的行为感到困惑:

  1. DataFrameReader.jdbc
  2. Dataset.repartition

官方的文档DataFrameReader.jdbc的发言权就下列numPartitions参数

numPartitions : 分区数。这与lowerBound(包含)、upperBound(不包含)一起形成用于生成的WHERE 子句表达式的分区步幅,用于均匀地拆分列columnName。

官方的文档Dataset.repartition发言权

返回一个具有精确numPartitions分区的新数据集。


我目前的理解:

  1. 方法中的numPartition参数DataFrameReader.jdbc控制从数据库读取数据的并行度
  2. numPartition参数Dataset.repartition控制输出文件的数量时,这将生成DataFrame将被写入到磁盘

我的问题:

  1. 如果我DataFrame通过读取DataFrameReader.jdbc然后将其写入磁盘(不调用repartition方法),那么输出中的文件是否仍然与我DataFrame在调用后将其写到磁盘repartition上的文件一样多?
  2. 如果以上问题的答案是:
    • 是:那么repartitionDataFrame使用DataFrameReader.jdbc方法(带numPartitions参数)读取的方法上调用方法是多余的吗?
    • 否:那么请纠正我的理解错误。同样在这种情况下numPartitionsDataFrameReader.jdbc方法的参数不应该被称为“并行”之东西吗?

y2k*_*ham 11

简短回答:这两种方法中的参数行为(几乎)没有区别numPartitions


read.jdbc(..numPartitions..)

这里,numPartitions参数控制:

  1. 并行连接的数目,将被制成该MySQL(或任何其它RDBM用于读取数据DataFrame
  2. 读取的所有后续操作的并行度,DataFrame包括写入磁盘,直到对其repartition调用方法

repartition(..numPartitions..)

这里的numPartitions参数控制在执行任何操作(包括写入磁盘)时所表现出的并行度DataFrame


因此,基本上使用方法DataFrame在读取MySQL表上获得的spark.read.jdbc(..numPartitions..)行为相同(在对其执行的操作中表现出相同程度的并行性),就好像它是没有并行性的情况下读取的repartition(..numPartitions..),然后在其上调用该方法(显然具有相同的值numPartitions


要回答确切的问题:

如果我通过 DataFrameReader.jdbc 读取 DataFrame 然后将其写入磁盘(不调用重新分区方法),那么输出中的文件是否仍然与在调用重新分区后将 DataFrame 写入磁盘时一样多它?

是的

假定读出的任务已被并行化通过提供适当的参数(columnNamelowerBoundupperBoundnumPartitions),所有对所得操作DataFrame 包括写入将被并行地执行。在这里引用官方文档

numPartitions:可用于表读写并行的最大分区数。这也决定了并发 JDBC 连接的最大数量。如果要写入的分区数超过此限制,我们会在写入前通过调用 coalesce(numPartitions) 将其减少到此限制。


是:那么在使用 DataFrameReader.jdbc 方法(使用 numPartitions 参数)读取的 DataFrame 上调用 repartition 方法是多余的吗?

是的

除非您调用repartition方法的其他变体(带columnExprs参数的变体),否则调用repartition这样的DataFrame(具有相同的numPartitions)参数是多余的。但是,我不确定在已经并行化的数据上强制执行相同程度的并行性是否也会不必要地调用数据混洗。一旦我遇到它会更新答案。 DataFrameexecutors