当前位置: 首页 > 知识库问答 >
问题:

Spark SQL在从Hive表加载数据时如何决定它将使用的分区数量?

陶健
2023-03-14

该问题与通过从Hive表中读取数据而创建的spark数据帧的分区数量相同

但我认为这个问题没有得到正确答案。请注意,问题是,当使用SparkSession对HIVE表执行sql查询而创建数据帧时,将创建多少个分区。sql方法。

IIUC,上面的问题不同于询问当执行诸如spark.read.json(“examples/src/main/resources/ppeople.json”)之类的代码直接从文件系统(可能是HDFS)加载数据时,将创建多少个分区。我认为后一个问题的答案由spark.sql.files.maxPartitionBytes给出

spark.sql.files.max分区字节134217728 (128 MB) 读取文件时要打包到单个分区中的最大字节数。

在实验中,我尝试从一个HIVE表创建一个dataframe,但我得到的分区数不能用< code > total data in HIVE table/spark . SQL . files . maxpartitionbytes 来解释

此外,添加到OP中,最好知道如何控制分区的数量,即当一个人想要强制spark使用与默认情况不同的数量时。

引用:

https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/SparkSession.scala

https://github . com/Apache/spark/blob/master/SQL/core/src/main/Scala/org/Apache/spark/SQL/dataset . Scala

共有1个答案

叶文博
2023-03-14

TL;DR:从 Hive 读取数据时的默认分区数将由 HDFS 块大小控制。可以通过将映射还原.job.map 设置为适当的值来增加分区数,也可以通过将映射还原.input.file输入格式.split.minsize 设置为适当的值来减少分区数

Spark SQL在从配置单元表加载数据时创建Hadoop RDD的实例。

一种RDD,它提供核心功能,用于读取存储在Hadoop中的数据(例如,HDFS中的文件,HBase中的源或S3),使用较旧的MapReduce API(组织.apache.hadoop.mapred)。

HadoopRDD进而根据org . Apache . Hadoop . MapReduce . lib . input . file input format(新API)和org . Apache . Hadoop . map red . file input format(旧API)中定义的< code>computeSplitSize方法拆分输入文件。

新API:

protected long computeSplitSize(long blockSize, long minSize,
                                  long maxSize) {
    return Math.max(minSize, Math.min(maxSize, blockSize));
  }

旧接口:

protected long computeSplitSize(long goalSize, long minSize,
                                       long blockSize) {
    return Math.max(minSize, Math.min(goalSize, blockSize));
  }

computeSplitSize根据HDFS块大小拆分文件,但如果块大小小于minSize或大于maxSize,则将其钳位到这些极端。HDFS块大小可以从

hdfs getconf -confKey dfs.blocksize

根据Hadoop的权威指南表8.5,最小尺寸是从mapreduce.input.file输入格式.split.minsize获得的,而maxSize是从mapreduce.input.file输入格式.split.maxsize获得的。

然而,书中也提到关于mapreduce.input.fileinputformat.split.maxsize

此属性在旧的MapReduce API中不存在(除了CombineFileInputFormat)。相反,它被间接计算为作业总输入的大小,除以mapreduce.job.maps(或JobConf上的setNumMapTask()方法)指定的映射任务的引导数。

本文还使用总输入大小除以地图任务数来计算maxSize。

 类似资料:
  • 即使它是Hive表或HDFS文件,当Spark读取数据并创建数据帧时,我也在想RDD /数据帧中的分区数将等于HDFS中的部分文件数。但是,当我使用 Hive 外部表进行测试时,我可以看到该数字与 部件文件的数量 不同。数据帧中的分区数为 119。该表是一个 Hive 分区表,其中包含 150 个部分文件,最小文件大小为 30 MB,最大大小为 118 MB。那么是什么决定了分区的数量呢?

  • 我对Hadoop(HDFS和Hbase)和Hadoop生态系统(Hive、Pig、Impala等)相当陌生。我已经很好地理解了Hadoop组件,如NamedNode、DataNode、Job Tracker、Task Tracker,以及它们如何协同工作以高效的方式存储数据。 null

  • 是否有一种方法可以从S3中自动化这个加载过程,以便表列数据类型可以从CSV文件中推断出来,或者通过其他方式在其他地方指定?(类似于在Google BigQuery中使用推断的表模式从GCS中的csv文件创建表的方式)

  • insert overwrite from select语句中的配置单元动态分区没有加载动态分区的数据,而是提供了数据配置单元默认分区。 如果我说显示分区表2; 它只给出一个分区细节,即配置单元默认分区 我有一个没有任何分区的暂存表,它从序列文件中读取数据。 如果不存在,则创建外部表table1(DS字符串、col1字符串、col2字符串、col3字符串) 行格式分隔字段,以存储为SEQUENCE