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);
相關文章
- Python如何處理檔案的?Python
- python 檔案處理Python
- python處理檔案Python
- python檔案處理Python
- 關於丟失表空間資料檔案的處理方式
- python處理txt檔案Python
- window 批處理檔案
- Python之檔案處理Python
- Go xml檔案處理GoXML
- 乾貨!Apache Hudi如何智慧處理小檔案問題Apache
- error的處理方式Error
- 處理 Linux 檔案的 3 個技巧Linux
- 匯出處理耗時的檔案
- 實踐場景:解決Spark流處理產生的小檔案Spark
- node js 處理PDF檔案JS
- 控制檔案損壞處理
- Python批處理:檔案操作Python
- python ini 配置檔案處理Python
- 使用 Python 處理 CSV 檔案Python
- ultracompare22,檔案處理
- java 檔案處理 工具類Java
- Python 如何處理大檔案Python
- Hadoop檢視檔案///hadoop 清洗檔案出現亂碼Hadoop
- 使用資料流的思想處理檔案
- Python處理CSV檔案的幾個方法Python
- 聊聊專案中定時任務的處理方式
- java自己封裝檔案處理Java封裝
- 001.00 一般檔案處理
- Excel VBA 利用FileSystemObject處理檔案ExcelObject
- Python筆記(五)——檔案處理Python筆記
- 用c語言處理檔案C語言
- java中 檔案壓縮處理Java
- Go 語言處理 yaml 檔案GoYAML
- 前端如何處理xml配置檔案?前端XML
- SpringBoot-檔案壓縮處理Spring Boot
- webpack(5)webpack處理css檔案WebCSS
- 字元編碼與檔案處理字元
- SPM12之fMRI批次預處理——NII檔案處理