看過很多Hadoop介紹或者是學習的帖子和文章,發現介紹Hadoop I/O系統的很少。很多文章都會介紹HDFS的架構和使用,還有MapReduce編程等等。尤其是在介紹Hadoop的MapReduce編程之前,首先必須了解下Hadoop的I/O知識,要不一看到IntWritable、LongWritable、Text、NullWritable等概念就有點犯暈,看到和普通的Java程序類似的MapReduce程序就覺得很難。如果這時候你知道其實IntWritable就是其他語言如Java、C++裡的int類型,LongWritable就是其他語言裡的long,Text類似String,NullWritable就是Null,這樣你就會很輕易的明白Hadoop 的MapReduce 程序。就像在學習其他編程語言之前必須先學習數據類型一樣,在學習Hadoop的MapReduce編程之前,最好先學習下Hadoop的I/O知識。這裡就簡要介紹Hadoop的I/O知識,就當拋磚引玉吧。
1序列化和反序列化
序列化(Serialization)就是結構化的對象轉化為字節流,這樣可以方便在網絡上傳輸和寫入磁盤進行永久存儲(原因看完這部分後就明白了)。反序列化(deserialization)就是指將字節流轉回結構化對象的逆過程。
序列化和反序列化在分布式數據處理裡主要出現在進程間通行和永久存儲兩個應用領域。在Hadoop 系統中,系統中多個節點上的進程間通信是通過遠程過程調用(romote procedure call,R PC)實現的,RPC協議將消息序列轉化為二進制流後發送到遠程節點,遠程節點接著將二進制流反序列化為消息,所以RPC對於序列化有以下要求(也就是進程間通信對於序列化的要求):
(1)緊湊,緊湊的格式可以提高傳輸效率,充分利用網絡帶寬,要知道網絡帶寬是數據中心的一種非常重要的資源。
(2)快速,進程間通信是分布是系統的重要內容,所以必須減少序列化和反序列化的開銷,這樣可以提高整個分布式系統的性能。
(3)可擴展,通信協議為了滿足一些新的需求,比如在方法調用的過程中增加新的參數,或者新的服務器系統要能夠接受老客戶端的舊的格式的消息,這樣就需要直接引進新的協議,序列化必須滿足可擴展的要求。
(4)互操作,可以支持不同語言寫的客戶端(比如C++、java、Python等等)與服務器交互。
前面說了序列化的目的是可以方便在網絡上傳輸和寫入磁盤進行永久存儲,前面講了進程間通信對於序列化的要求,下面來說一說數據永久存儲對於序列化的要求。前面說的4個序列化的要求也是數據永久存儲所要求的,存貯格式緊湊可以高效的利用存儲空間,快速可以減少讀寫數據的額外開銷,可擴張這樣就可以方便的讀取老格式的數據,互操作就可以滿足不同的編程序言來讀寫永久存貯的數據。