Hadoop小文件弊端
每個文件均按塊存儲,每個塊的元數據存儲在NameNode的內存中,因此HDFS存儲小文件會非常低效。因爲大量的小文件會耗盡NameNode中的大部分內存。但注意,存儲小文件所需要的磁盤容量和數據塊的大小無關。例如,一個1MB的文件設置爲128MB的塊存儲,實際使用的是1MB的磁盤空間,而不是128MB。
HDFS上每個文件都要在NameNode上創建對應的元數據,這個元數據的大小約爲150byte,這樣當小文件比較多的時候,就會產生很多的元數據文件,一方面會大量佔用NameNode的內存空間,另一方面就是元數據文件過多,使得尋址索引速度變慢。
小文件過多,在進行MR計算時,會生成過多切片,需要啓動過多的MapTask。每個MapTask處理的數據量小,導致MapTask的處理時間比啓動時間還小,白白消耗資源。
Hadoop小文件解決方案
1)(數據源頭)
在數據採集的時候,就將小文件或小批數據合成大文件再上傳HDFS
2)Hadoop Archive(存儲方向)
是一個高效的將小文件放入HDFS塊中的文件存檔工具,能夠將多個小文件打包成一個HAR文件,從而達到減少NameNode的內存使用。具體說來,HDFS存檔文件對內還是一個一個獨立文件,對NameNode而言卻是一個整體,減少了NameNode的內存。
3)CombineTextInputFormat(計算方向)
CombineTextInputFormat用於將多個小文件在切片過程中生成一個單獨的切片或者少量的切片。
4)開啓uber模式,實現JVM重用(計算方向)
默認情況下,每個Task任務都需要啓動一個JVM來運行,如果Task任務計算的數據量很小,我們可以讓同一個Job的多個Task運行在一個JVM中,不必爲每個Task都開啓一個JVM。
(1)未開啓uber模式,在/input路徑上上傳多個小文件並執行wordcount程序
[lytfly@hadoop102 hadoop-3.1.4]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.4.jar wordcount /input /output2
(2)觀察控制檯
2021-02-14 16:13:50,607 INFO mapreduce.Job: Job job_1613281510851_0002 running in uber mode : false
(3)觀察http://hadoop103:8088/cluster
(4)開啓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>128</value>
</property>
(5)分發配置
[atguigu@hadoop102 hadoop]$ xsync mapred-site.xml
(6)再次執行wordcount程序
[atguigu@hadoop102 hadoop-3.1.4]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.4.jar wordcount /input /output2
(7)觀察控制檯
2021-02-14 16:28:36,198 INFO mapreduce.Job: Job job_1613281510851_0003 running in uber mode : true