【发布时间】:2020-03-02 02:02:05
【问题描述】:
Spark 在读取文件时如何决定分区数?
假设我们在 hdfs 目录中有一个 10 GB 的单个文件,在另一个 hdfs 位置有多个总 10 GB 卷的部分文件。
如果这两个文件在两个单独的 spark 数据帧中读取,它们的分区数是多少,基于什么逻辑?
【问题讨论】:
标签: apache-spark pyspark apache-spark-sql pyspark-dataframes
Spark 在读取文件时如何决定分区数?
假设我们在 hdfs 目录中有一个 10 GB 的单个文件,在另一个 hdfs 位置有多个总 10 GB 卷的部分文件。
如果这两个文件在两个单独的 spark 数据帧中读取,它们的分区数是多少,基于什么逻辑?
【问题讨论】:
标签: apache-spark pyspark apache-spark-sql pyspark-dataframes
在How to: determine partition找到信息 它说:
这个数字是如何确定的?上一篇文章中描述了 Spark 将 RDD 分组为阶段的方式。 (快速提醒一下,像 repartition 和 reduceByKey 这样的转换会导致阶段边界。)阶段中的任务数与阶段中最后一个 RDD 中的分区数相同。 RDD 中的分区数与其所依赖的 RDD 中的分区数相同,但有几个例外:coalesce 转换允许创建一个分区少于其父 RDD 的 RDD,union 转换创建一个具有其父母的分区数的总和,笛卡尔用他们的产品创建一个RDD。
没有父母的 RDD 怎么办?由 textFile 或 hadoopFile 生成的 RDD 的分区由使用的底层 MapReduce InputFormat 确定。通常,每个被读取的 HDFS 块都会有一个分区。 parallelize 生成的 RDD 的分区来自用户给定的参数,如果没有给定参数,则来自 spark.default.parallelism。
当 Spark 从 HDFS 读取文件时,它会为单个输入拆分创建单个分区。输入拆分由用于读取此文件的 Hadoop InputFormat 设置。例如,如果您使用 textFile() 它将是 Hadoop 中的 TextInputFormat,它将为您返回单个 HDFS 块的单个分区(但分区之间的拆分将在行拆分时完成,而不是确切的块拆分),除非你有一个压缩的文本文件。如果是压缩文件,您将获得单个文件的单个分区(因为压缩的文本文件不可拆分)。
如果您有一个 10GB 的未压缩文本文件存储在 HDFS 上,那么使用默认的 HDFS 块大小设置 (128MB) 它将存储在 79 个块中,这意味着您从该文件中读取的 RDD 将具有 79 个分区。
另外,如果对spark默认提供的分区数不满意,我们可以传递我们想要的分区数,如下所示:
>>> rdd1 = sc.textFile("statePopulations.csv",10) // 10 is number of partitions
【讨论】: