针对Hive表的分区,Spark对每个分区都构建了一个HadoopRDD,每个分区目次下就是实际的数据文件,例如我们集群的某一张表按天禀区,天世界面有200个数据文件,每个文件大年夜概3MB~4MB之间,这些实际上是reduce设置不合理导致的小文件产生,如下图

此处 listStatus 办法就是扫描的分区目次,它返回的就是图中显示的具体 part-*****文件的FileStatus对象,一共200个。大年夜 totalSize 的计算可以看出,它是这200个文件的总大年夜小,为838MB,是以 goalSize 就为419MB。
参数 mapreduce.input.fileinputformat.split.minsize 在Spark法度榜样没有配的情况下,获取的值为0,而 minSplitSize在Spark获取FileSplits的时刻并没有被设置,所认为默认值1,那么 minSize 就为1
其次,我们再来看大年夜文件划分Split,部分代码如下(部分化释见注释)
- ArrayList splits = new ArrayList(numSplits);
- NetworkTopology clusterMap = new NetworkTopology();
- // files是膳绫擎扫描的分区目次下的part-*****文件
- for (FileStatus file: files) {
- Path path = file.getPath();
- long length = file.getLen();
- if (length != 0) {
- FileSystem fs = path.getFileSystem(job);
- BlockLocation[] blkLocations;
- if (file instanceof LocatedFileStatus) {
- blkLocations = ((LocatedFileStatus) file).getBlockLocations();
- } else {
- blkLocations = fs.getFileBlockLocations(file, 0, length);
- }
- // 断定文件是否可切割
- if (isSplitable(fs, path)) {
- // 这里获取的不是文件本身的大年夜小,它的大年夜小大年夜膳绫擎的length就可以知道,这里获取的是HDFS文件块(跟文件本身没有关系)的大年夜小
- // HDFS文件块的大年夜小由两个参数决定,分别是 dfs.block.size 和 fs.local.block.size
- // 在HDFS集群模式下,由 dfs.block.size 决定,对于Hadoop2.0来说,默认值是128MB
- // 在HDFS的local模式下,由 fs.local.block.size 决定,默认值是32MB
- long blockSize = file.getBlockSize(); // 128MB
推荐阅读
【限时免费】岁尾最强一次云计算大年夜会,看传统、社区、互联网企业若何碰撞? 之后是7nm的Navi(仙后座),再之后是基于7nm+改进版的下下代架构。据ComputerBase报道,代号GFX10的芯片近>>>详细阅读
本文标题:从源码看Spark读取Hive表数据小文件和分块的问题
地址:http://www.17bianji.com/lsqh/40042.html
1/2 1