hadoop SequenceFile 簡介/優缺點
1. 什麼是SequenceFile
1.1.sequenceFile檔案是Hadoop用來儲存二進位制形式的[Key,Value]對而設計的一種平面檔案(Flat File)。
1.2.可以把SequenceFile當做是一個容器,把所有的檔案打包到SequenceFile類中可以高效的對小檔案進行儲存和處理。
1.3.SequenceFile檔案並不按照其儲存的Key進行排序儲存,SequenceFile的內部類Writer提供了append功能。
1.4.SequenceFile中的Key和Value可以是任意型別Writable或者是自定義Writable。
1.5.在儲存結構上,SequenceFile主要由一個Header後跟多條Record組成,Header主要包含了Key classname,value classname,儲存壓縮演算法,使用者自定義元資料等資訊,此外,還包含了一些同步標識,用於快速定位到記錄的邊界。每條Record以鍵值對的方式進行儲存,用來表示它的字元陣列可以一次解析成:記錄的長度、Key的長度、Key值和value值,並且Value值的結構取決於該記錄是否被壓縮。
2.SequenceFile支援資料壓縮
2.1.SequenceFIle的內部格式取決於是否啟用壓縮,如果是壓縮,則又可以分為記錄壓縮和塊壓縮。
2.2.有一下三種類型的壓縮:
A.無壓縮型別:如果沒有啟用壓縮(預設設定)那麼每個記錄就由它的記錄長度(位元組數)、鍵的長度,鍵和值組成。長度欄位為4位元組。
B.記錄壓縮型別:記錄壓縮格式與無壓縮格式基本相同,不同的是值位元組是用定義在頭部的編碼器來壓縮。注意:鍵是不壓縮的。下圖為記錄壓縮:
C.塊壓縮型別:塊壓縮一次壓縮多個記錄,因此它比記錄壓縮更緊湊,而且一般優先選擇。當記錄的位元組數達到最小大小,才會新增到塊。該最小值由io.seqfile.compress.blocksize中的屬性定義。預設值是1000000位元組。格式為記錄數、鍵長度、鍵、值長度、值。下圖為塊壓縮:
3.優缺點
SequenceFile優點:
A.支援基於記錄(Record)或塊(Block)的資料壓縮。
B.支援splitable,能夠作為MapReduce的輸入分片。
C.修改簡單:主要負責修改相應的業務邏輯,而不用考慮具體的儲存格式。
SequenceFile的缺點
A.需要一個合併檔案的過程,且合併後的檔案不方便檢視。
4.具體程式碼實現
以下程式碼實現了讀寫SequenceFile的需求。
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.*; import org.apache.hadoop.util.ReflectionUtils; import java.io.IOException; public class SequenceTest { public static final String output_path = "xxx"; private static final String[] DATA = { "a", "b", "c", "d"}; @SuppressWarnings("deprecation") public static void write(String pathStr) throws IOException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); Path path = new Path(pathStr); SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf, path, Text.class, IntWritable.class); Text key = new Text(); IntWritable value = new IntWritable(); for(int i = 0; i < DATA.length; i++) { key.set(DATA[i]); value.set(i); System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value); writer.append(key, value); } IOUtils.closeStream(writer); } @SuppressWarnings("deprecation") public static void read(String pathStr) throws IOException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); Path path = new Path(pathStr); SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf); Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf); Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf); while (reader.next(key, value)) { System.out.printf("%s\t%s\n", key, value); } IOUtils.closeStream(reader); } public static void main(String[] args) throws IOException { write(output_path); read(output_path); } }