HDFS小文件优化
1. 小文件弊端
HDFS 上每个文件都要在NameNode 上创建对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,就会产生很多的元数据文件,一方面会大量占用NameNode 的内存空间,另一方面就是元数据文件过多,使得寻址索引速度变慢
小文件过多,在进行MR 计算时,会生成过多切片,需要启动过多的 MapTask。每个
MapTask 处理的数据量小,导致 MapTask 的处理时间比启动时间还小,白白消耗资源
2. 小文件解决方案
2.1 数据源头
在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS
2.2 存储方向
Hadoop Archive是一个高效的将小文件放入HDFS 块中的文件存档工具,能够将多个小文件打包成一个HAR文件,HAR文件对内还是一个一个独立文件,对 NameNode 而言却是一个整体,从而达到减少 NameNode的内存使用
-
归档文件
把/inputs 目录里面的所有文件归档成一个叫 inputs.har 的归档文件,并把归档后文件存储到/output 路径下[codecat@hadoop102 hadoop-3.1.3]$ hadoop archive -archiveName inputs.har -p /inputs /output
-
查看归档
[codecat@hadoop102 hadoop-3.1.3]$ hadoop fs -ls /output/inputs.har Found 4 items -rw-r--r-- 3 codecat supergroup 0 2021-09-27 19:49 /output/inputs.har/_SUCCESS -rw-r--r-- 3 codecat supergroup 284 2021-09-27 19:49 /output/inputs.har/_index -rw-r--r-- 3 codecat supergroup 23 2021-09-27 19:49 /output/inputs.har/_masterindex -rw-r--r-- 3 codecat supergroup 516 2021-09-27 19:49 /output/inputs.har/part-0 [codecat@hadoop102 hadoop-3.1.3]$ hadoop fs -ls har:///output/inputs.har Found 3 items -rw-r--r-- 3 codecat supergroup 193 2021-09-27 19:37 har:///output/inputs.har/hello.txt -rw-r--r-- 3 codecat supergroup 80 2021-09-27 19:37 har:///output/inputs.har/kv.txt -rw-r--r-- 3 codecat supergroup 243 2021-09-27 19:37 har:///output/inputs.har/nline.txt
-
解归档文件
[codecat@hadoop102 hadoop-3.1.3]$ hadoop fs -cp har:///output/inputs.har/* /
2.3 计算方向
2.3.1 CombineTextInputFormat
CombineTextInputFormat 用于将多个小文件在切片过程中生成一个单独的切片或者少
量的切片。
2.3.2 开启 uber 模式,实现 JVM 重用
默认情况下,每个 Task 任务都需要启动一个JVM 来运行,如果 Task 任务计算的数据量很小,我们可以让同一个 Job 的多个 Task 运行在一个 JVM 中,不必为每个 Task 都开启一个 JVM
-
未开启
uber模式,在/inputs路径上上传多个小文件并执行wordcount程序[codecat@hadoop102 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /inputs /output

-
开启
uber模式,在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> -
再次执行
wordcount程序[codecat@hadoop102 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /inputs /output1
