蚂蚁绊倒大象,不起眼的小文件竟拖了Hadoop大数据的后腿

HDFS作为Hadoop生态系统的分布式文件系统,它被设计用来存储海量数据,特别是TB、PB量级别的数据。它的设计的初衷也是存储大文件,而如果HDFS上存在大量的小文件,会对系统性能带来严重的问题。本文想跟大家聊下小文件的处理。

HDFS作为Hadoop生态系统的分布式文件系统,它被设计用来存储海量数据,特别是TB、PB量级别的数据。它的设计的初衷也是存储大文件,而如果HDFS上存在大量的小文件,会对系统性能带来严重的问题。本文想跟大家聊下小文件的处理。

本文的小文件是指那些大小比HDFS的block (Hadoop 2.x的默认大小128MB)小的多的文件。在HDFS中,文件元信息,例如位置、大小、分块信息等这些存储在Namenode的内存中,每一个object占用150 bytes的内存。文件个数越多相应的也会占用Namenode更多的内存。何况HDFS主要是为了流式的访问大文件而设计的,读取众多的小文件显然也是非常低效的。

Hadoop小文件的3类常见情况的处理

1、HDFS中存储包含了大量小文件

现象:在HDFS上已经存在了大量的小文件和目录。

方案:通过调用HDFS的sync()方法和append()方法,将小文件和目录每隔一定时间生成一个大文件,或者可以通过写程序来合并这些小文件。

2、MapReduce的输入包含大量小文件

现象:输入文件中存在大量的小文件

MapReduce程序的Map任务(task)一次可以处理一个块(block)大小的输入数据(默认使用FileInputFormat)。如果一个输入文件的大小大于block,那么会拆成两个或多个task进行处理;如果小于block,也会用一个task处理该文件。需要处理的数据如果分散存储在许多小文件中,就会产生大量的map task,如果小文件个数非常多,这会使处理时间变的很慢。

方案:有3种

1)Hadoop Archive:

Hadoop Archive是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将许多小文件打包成一个HAR文件,这样会同时减少Namenode的内存使用。

2)Sequence File:

Sequence File由一系列的二进制key/value组成,如果key为小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。

1)和2)这里不做介绍,可以参考 ⬇️

http://blog.cloudera.com/blog/2009/02/the-small-files-problem

3)CombineFileInputFormat:

Hadoop有一个专门的类CombineFileInputFormat 来处理小文件,它根据一定的规则,将HDFS上多个小文件合并到一个InputSplit中,同时启动适量的Map来处理这里面的文件,以减少MR整体作业的运行时间。CombineFileInputFormat类继承FileInputFormat,主要重写了List<InputSplit> getSplits(JobContext var1)方法,我们可以设置mapreduce.input.fileinputformat.split.minsize.per.node、mapreduce.input.fileinputformat.split.minsize.per.rack和mapreduce.input.fileinputformat.split.maxsize 参数的设置来合并小文件。其中mapreduce.input.fileinputformat.split.maxsize参数至关重要,如果没有设置这个参数(默认没设置),那么同一个机架上的所有小文件将组成一个InputSplit,最终由一个Map Task来处理。如果设置了这个参数,那么同一个节点(node)上的文件将会组成一个InputSplit。

InputSplit包含的HDFS块信息存储在CombineFileSplit 类中。该类包含了每个块文件的路径、起始偏移量、相对于原始偏移量的大小和这个文件的存储节点。CombineTextInputFormat告诉MR程序如何读取组合的InputSplit,具体如何解析CombineFileSplit中的文件主要在CombineFileRecordReader中实现。该类封装了TextInputFormat的RecordReader,并对CombineFileSplit中的多个文件循环遍历并读取其中的内容。

样例代码如下:

2018101707251598

日志输出:

2018101707250295

 

可以从日志中很清楚的看出input文件数为Total input paths to process : 152,通过CombineFileInputFormat处理后splits为mapreduce.JobSubmitter: number of splits:1,map数为Launched map tasks=1。可以修改mapreduce.input.fileinputformat.split.maxsize参数,观察Map Task的个数变化。

3、Hive小文件问题

现象1: hive输入的文件过多

方案:设置mapper 输入文件合并参数

 

1

现象2:hive执行中间过程生成的文件过多

方案:设置中间过程合并参数,尽量避免小文件

2

现象3:hive输出结果生成的文件过多

方案:一种是调整reducer个数,另一种是调整reducer大小

3

/ 参考文章 /

1、https://hadoop.apache.org/docs/r2.7.1/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html

2、https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties

3、http://blog.cloudera.com/blog/2009/02/the-small-files-problem/

去年今日运营文章

  1. 2023:  如何发现自我优势?(0)
  2. 2023:  知名企业商业画布合集(0)
  3. 2022:  实体门店数字化转型的重要因素(数字化转型的重要因素是什么)(0)
  4. 2022:  私域运营中,企业私域流量运营的步骤有哪些(0)
  5. 2022:  支付宝已支持给微信QQ好友转账(0)

本文由Analysys-Yiguan投稿,不代表爱运营立场,如若转载,请注明出处:https://www.iyunying.org/seo/sjfx/150357.html

(0)
Analysys-Yiguan的头像Analysys-Yiguan投稿者
上一篇 2018年10月17日 上午10:03
下一篇 2018年10月19日 下午9:18

发表回复

登录后才能评论
分享本页
返回顶部