此问题与Number of partitions of a spark dataframe created by reading the data from Hive table
相同但我认为这个问题得不到正确答案。请注意,问题是当使用SparkSession.sql方法对HIVE表执行sql查询而创建数据帧时,将询问将创建多少个分区。
IIUC,上面的问题不同于在创建数据帧时会创建多少分区,因为执行了一些像spark.read.json("examples/src/main/resources/people.json")
这样直接从文件系统加载数据的代码 - 可能是HDFS。我认为后一个问题的答案由spark.sql.files.maxPartitionBytes
spark.sql.files.maxPartitionBytes 134217728(128 MB)最大值 读取文件时要打包到单个分区的字节数。
实验上,我尝试从HIVE表创建一个数据框,total data in hive table / spark.sql.files.maxPartitionBytes
同时添加到OP,最好知道如何控制分区的数量,即当人们想要强制使用与默认情况下不同的数字时使用火花。
参考文献:
答案 0 :(得分:8)
TL; DR:从Hive读取数据时的默认分区数将由HDFS blockSize控制。通过将mapreduce.job.maps设置为适当的值可以增加分区数,可以通过将mapreduce.input.fileinputformat.split.minsize设置为适当的值来减少分区数
从hive表加载数据时,Spark SQL会创建HadoopRDD的实例。
RDD,提供读取存储的数据的核心功能 Hadoop(例如,HDFS中的文件,HBase中的文件或S3),使用旧版本 MapReduce API(org.apache.hadoop.mapred)。
HadoopRDD依次根据org.apache.hadoop.mapreduce.lib.input.FileInputFormat(新API)和org.apache.hadoop.mapred.FileInputFormat(旧API)中定义的computeSplitSize
方法拆分输入文件。
新API:
protected long computeSplitSize(long blockSize, long minSize,
long maxSize) {
return Math.max(minSize, Math.min(maxSize, blockSize));
}
旧API:
protected long computeSplitSize(long goalSize, long minSize,
long blockSize) {
return Math.max(minSize, Math.min(goalSize, blockSize));
}
computeSplitSize根据HDFS blockSize拆分文件,但如果blockSize小于minSize
或大于maxSize
,那么它将被限制在那些极端。 HDFS blockSize可以从
hdfs getconf -confKey dfs.blocksize
根据Hadoop最终指南表8.5,minSize
是从mapreduce.input.fileinputformat.split.minsize
获得的,maxSize
是从mapreduce.input.fileinputformat.split.maxsize
获得的。
但是,该书还提到mapreduce.input.fileinputformat.split.maxsize
:
此属性不存在 在旧的MapReduce API中(除了 CombineFileInputFormat)。相反,它是间接计算的 作业总输入的大小除以指南编号 mapreduce.job.maps(或setNumMapTasks()指定的map任务 JobConf上的方法。
this post还使用总输入大小除以map任务数来计算maxSize。