Hadoop小檔案的處理方式
一、將小檔案合併成歸檔檔案
- Archive簡稱為HAR,是一個高效地將小檔案放入HDFS塊中的檔案存檔工具,它能夠將多個小檔案打包成一個HAR檔案,這樣在減少namenode記憶體使用的同時,仍然允許對檔案進行透明的訪問
- HAR是建立在HDFS基礎之上的一個檔案系統,因此所有fs shell命令對HAR檔案均可用,只不過是檔案路徑格式不一樣,HAR的訪問路徑可以是以下兩種格式:
har://scheme-hostname:port/archivepath/fileinarchive
har:///archivepath/fileinarchive(本節點)
3.這種方式不足之處,比如:a. 一旦建立,Archives便不可改變。要增加或移除裡面的檔案,必須重新建立歸檔檔案
b.要歸檔的檔名中不能有空格,否則會丟擲異常,可以將空格用其他符號替換。
二.SequenceFile
- SequenceFile檔案是Hadoop用來儲存二進位制形式的key-value對而設計的一種平面檔案(Flat File)。
- 目前,也有不少人在該檔案的基礎之上提出了一些HDFS中小檔案儲存的解決方案,他們的基本思路就是將小檔案進行合併成一個大檔案,同時對這些小檔案的位置資訊構建索引
- 檔案不支援複寫操作,不能向已存在的SequenceFile(MapFile)追加儲存記錄
- 當write流不關閉的時候,沒有辦法構造read流。也就是在執行檔案寫操作的時候,該檔案是不可讀取的
程式碼示例
程式碼如下(示例):
@Test
/**
* SequenceFile 讀操作
*/
public void sequenceRead() throws Exception {
final String INPUT_PATH = "hdfs://192.168.242.101:9000/big/big.seq";
// 獲取檔案系統
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://192.168.242.101:9000");
FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
// 準備讀取seq的流
Path path = new Path(INPUT_PATH);
SequenceFile.Reader reader = new SequenceFile.Reader(fileSystem, path, conf);
// 通過seq流獲得key和value
Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);
Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf);
// 迴圈從流中讀取key和value
long position = reader.getPosition();
while (reader.next(key, value)) {
// 列印當前key value
System.out.println(key + ":" + value);
// 移動遊標指向下一個key value
position = reader.getPosition();
}
// 關閉流
IOUtils.closeStream(reader);
}
@Test
/**
* 多個小檔案合併成大seq檔案
*
* @throws Exception
*/
public void small2Big() throws Exception {
final String INPUT_PATH = "hdfs://192.168.242.101:9000/small";
final String OUTPUT_PATH = "hdfs://192.168.242.101:9000/big/big.seq";
// 獲取檔案系統
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://192.168.242.101:9000");
FileSystem fs = FileSystem.get(conf);
// 通過檔案系統獲取所有要處理的檔案
FileStatus[] files = fs.listStatus(new Path(INPUT_PATH));
// 建立可以輸出seq檔案的輸出流
Text key = new Text();
Text value = new Text();
SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf, new Path(OUTPUT_PATH), key.getClass(),
value.getClass());
// 迴圈處理每個檔案
for (int i = 0; i < files.length; i++) {
// key設定為檔名
key.set(files[i].getPath().getName());
// 讀取檔案內容
InputStream in = fs.open(files[i].getPath());
byte[] buffer = new byte[(int) files[i].getLen()];
IOUtils.readFully(in, buffer, 0, buffer.length);
// 值設定為檔案內容
value.set(buffer);
// 關閉輸入流
IOUtils.closeStream(in);
// 將key檔名value檔案內容寫入seq流中
writer.append(key, value);
}
}
三、CompositeInputFormat
- 用於多個資料來源的join
- 此類可以解決多個小檔案在進行mr操作時map建立過多的問題
- 此類的原理在於,它本質上是一個InputFormat,在其中的getSplits方法中,將他能讀到的所有的檔案生成一個InputSplit
- 使用此類需要配合自定義的RecordReader,需要自己開發一個RecordReader指定如何從InputSplit中讀取資料
也可以通過引數控制最大的InputSplit大小 – CombineTextInputFormat.setMaxInputSplitSize(job, 25610241024);
相關文章
- Hadoop 中處理小檔案的方式, Avro應用HadoopVR
- avro處理hadoop上的小檔案VRHadoop
- Hadoop Archives 小資料處理HadoopHive
- [R]檔案處理
- bat處理檔案BAT
- bat檔案處理BAT
- UNIX的檔案處理(轉)
- 關於丟失表空間資料檔案的處理方式
- Linux學習之檔案處理命令(二)目錄處理命令 && 檔案處理命令Linux
- 乾貨!Apache Hudi如何智慧處理小檔案問題Apache
- Python如何處理檔案的?Python
- 常見的檔案處理命令
- window 批處理檔案
- python處理檔案Python
- Go xml檔案處理GoXML
- python檔案處理Python
- python 檔案處理Python
- Python 檔案處理Python
- JAVA ZIP 處理檔案Java
- 批處理檔案命令
- 檔案處理函式函式
- Windows批處理檔案Windows
- bat批處理檔案BAT
- error的處理方式Error
- 縮小資料檔案尺寸報ORA-03297的處理辦法
- 實踐場景:解決Spark流處理產生的小檔案Spark
- 匯出處理耗時的檔案
- java 檔案處理 工具類Java
- python處理txt檔案Python
- laravel處理檔案上傳Laravel
- Python 批量處理檔案Python
- node js 處理PDF檔案JS
- Python處理大檔案Python
- 使用Java處理大檔案Java
- Python之檔案處理Python
- 通過原始碼的方式編譯hadoop的安裝檔案原始碼編譯Hadoop
- 上下居中的處理方式
- 引號的處理方式