1.小文件弊端
-
HDFS 上每个文件都要在 NameNode 上创建对应的元数据,这个元数据的大小约为 150byte,这样当小文件比较多的时候,就会产生很多的元数据文件。一方面会大量占用 NameNode 的内存空间(但注意,存储小文件所需要的磁盘容量和数据块的大小无关。例如,一个 1MB 的文件设置为 128MB 的块存储,实际使用的是 1MB 的磁盘空间,而不是 128MB。);另一方面就是元数据文件过多,使得寻址索引速度变慢。 -
小文件过多,在进行 MR 计算时,会生成过多切片,需要启动过多的 MapTask。每个 MapTask 处理的数据量小,导致 MapTask 的处理时间比启动时间还小,白白消耗资源。
2.小文件弊端的解决方案
下面将从数据源头方面、存储方面、计算方面等3方面给出关于小文件弊端的解决方案。
* 数据源头方面
在数据采集的时候,就将小文件或小批数据合成大文件再上传至 HDFS。
* 存储方面
Hadoop Archive(归档文件),是一个高效的将小文件放入 HDFS 块中的文件存档工具,能够将多个小文件打包成一个 HAR 文件,在减少 NameNode 内存使用的同时,允许对文件进行透明的访问。具体说来,HDFS 归档文件对内还是一个一个独立文件,对 NameNode 而言却是一个整体,减少了对 NameNode 内存的占用。
** 归档操作
(0)需要驱动 YARN 进程
start-yarn.sh
(1)归档文件 例如:把 /input 目录里面的所有文件归档成一个叫 input.har 的归档文件,并把归档后文件存储到 /output 路径下。
hadoop archive -archiveName input.har -p /input /output
** 查看归档文件
hadoop fs -ls har:///output/input.har
** 解归档文件
hadoop fs -cp har:///output/input.har/* /
* 计算方面
** CombineTextInputFormat
CombineTextInputFormat 用于将多个小文件在切片过程中生成一个单独的切片或者少量的切片。
** 开启 uber 模式,实现 JVM 重用
默认情况下,每个 Task 任务都需要启动一个 JVM 来运行,如果 Task 任务计算的数据量很小,我们可以让同一个 Job 的多个 Task 运行在一个 JVM 中,不必为每个 Task 都开启一个 JVM。
未开启 uber 模式时,我们可以在日志中看到如下提示:
INFO mapreduce.Job: Job job_1613281510851_0002 running in uber mode : false
配置文件:mapred-site.xml 配置参数:
<!-- 开启 uber 模式 ,默认关闭 -->
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<!-- uber 模式中最大的 mapTask 数量,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxmaps</name>
<value>9</value>
</property>
<!-- uber 模式中最大的 reduce 数量,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxreduces</name>
<value>1</value>
</property>
<!-- uber 模式中最大的输入数据量,默认使用 dfs.blocksize 的值,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxbytes</name>
<value></value>
</property>
开启 uber 模式后,我们可以在日志中看到如下提示:
INFO mapreduce.Job: Job job_1613281510851_0003 running in uber mode : true
|