SequenceFile和MapFile特點及生成RDD

   定期分享源碼,總結相關知識點,哈哈哈,來關注啊

概括

Hadoop 的 HDFS 和 MapReduce 子框架主要是針對大數據文件來設計的,在小文件的處理上不但效率低下,而且十分消耗內存資源(每一個小文件佔用一個 Block,每一個 block 的元數據都存儲在 namenode 的內存裏)。解決辦法通常是選擇一個容器,將這些小文件組織起來統一存儲。HDFS 提供了兩種類型的容器,分別是 SequenceFileMapFile

關於SequenceFile

概述

SequenceFile 是 Hadoop 的一個重要數據文件類型,它提供key-value的存儲,但與傳統key-value存儲(比如hash表)不同的是,它是appendonly的,於是你不能對已存在的key進行寫操作。

解決問題

該文件格式通常被用來解決hadoop中的小文件問題,相當於一個容器,把這些小文件組織起來統一存儲。

壓縮格式

SeqeunceFile支持兩種格式的數據壓縮,分別是:record compressionblock compression

存儲結構

在存儲結構上,SequenceFile 主要由一個 Header 後跟多條 Record 組成。
Header 主要包含了 Key classname,Value classname,存儲壓縮算法,用戶自定義元數據等信息,此外,還包含了一些同步標識,用於快速定位到記錄的邊界。
每條 Record 以鍵值對的方式進行存儲,用來表示它的字符數組可依次解析成:記錄的長度、Key 的長度、Key 值和 Value 值,並且 Value 值的結構取決於該記錄是否被壓縮

操作方式

SequenceFile 可通過如下 API 來完成新記錄的添加操作:
fileWriter.append(key,value)
可以看到,每條記錄以鍵值對的方式進行組織,但前提是 Key 和 Value 需具備序列化反序列化的功能

SequenceFile 讀/寫操作

1. Configuration conf=new Configuration();
2. FileSystem fs=FileSystem.get(conf);
3. Path seqFile=new Path("seqTestFile.seq");
4. //Reader 內部類用於文件的讀取操作
5. SequenceFile.Reader reader=new SequenceFile.Reader(fs,seqFile,conf);
6. //Writer 內部類用於文件的寫操作,假設 Key 和 Value 都爲 Text 類型
7. SequenceFile.Writer writer=new SequenceFile.Writer(fs,conf,seqFile,Text.class,Text.class);
8. //通過 writer 向文檔中寫入記錄
9. writer.append(new Text("key"),new Text("value"));
10. IOUtils.closeStream(writer);//關閉 write 流
11. //通過 reader 從文檔中讀取記錄
12. Text key=new Text();
13. Text value=new Text();
14. while(reader.next(key,value)){
15. System.out.println(key);
16. System.out.println(value);
17. }
18. IOUtils.closeStream(reader);//關閉 read 流

關於MapFile

介紹及組成

MapFile 是排序後的 SequenceFile,通過觀察其目錄結構可以看到 MapFile 由兩部分組成,分別是 data 和 index。
index 作爲文件的數據索引,主要記錄了每個 Record 的 key 值,以及該 Record 在文件中的偏移位置。在 MapFile 被訪問的時候,索引文件會被加載到內存,通過索引映射關係可迅速定位到指定 Record 所在文件位置,因此,相對SequenceFile 而言,MapFile 的檢索效率是高效的,缺點是會消耗一部分內存來存儲 index 數據。

與SequenceFile不同的是

MapFile 的 KeyClass 一定要實現 WritableComparable 接口,即 Key 值是可比較的。

MapFile 讀寫操作

. Configuration conf=new Configuration();
2. FileSystem fs=FileSystem.get(conf);
3. Path mapFile=new Path("mapFile.map");
4. //Reader 內部類用於文件的讀取操作
5. MapFile.Reader reader=new MapFile.Reader(fs,mapFile.toString(),conf);
6. //Writer 內部類用於文件的寫操作,假設 Key 和 Value 都爲 Text 類型
7. MapFile.Writer writer=new MapFile.Writer(conf,fs,mapFile.toString(),Text.class,Text.class);
8. //通過 writer 向文檔中寫入記錄
9. writer.append(new Text("key"),new Text("value"));
10. IOUtils.closeStream(writer);//關閉 write 流
11. //通過 reader 從文檔中讀取記錄
12. Text key=new Text();
13. Text value=new Text();
14. while(reader.next(key,value)){
15. System.out.println(key);
16. System.out.println(key);
17. }
18. IOUtils.closeStream(reader);//關閉 read 流

SequenceFile和MapFile的侷限性

1.文件不支持複寫操作,不能向已存在的 SequenceFile(MapFile)追加存儲記錄
2.當 write 流不關閉的時候,沒有辦法構造 read 流。也就是在執行文件寫操作的時候,該文件是不可讀取的

關於SquenceFile生成RDD與TextFile生成RDD的區別

因爲SequenceFile的分區和上一篇講的TextFile的分區非常類型,只有個別不一樣的地方

  @Override
  protected FileStatus[] listStatus(JobConf job) throws IOException {
    FileStatus[] files = super.listStatus(job);
    for (int i = 0; i < files.length; i++) {
      FileStatus file = files[i];
      if (file.isDirectory()) {     // it's a MapFile
        Path dataFile = new Path(file.getPath(), MapFile.DATA_FILE_NAME);
        FileSystem fs = file.getPath().getFileSystem(job);
        // use the data file
        files[i] = fs.getFileStatus(dataFile);
      }
    }
    return files;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章