天天看點

Hive 檔案格式

本文主要轉至:http://www.cnblogs.com/skyl/

Hadoop 作為MR 的開源實作,一直以動态運作解析檔案格式并獲得比MPP資料庫快上幾倍的裝載速度為優勢。不過,MPP資料庫社群也一直批評Hadoop由于檔案格式并非為特定目的而建,是以序列化和反序列化的成本過高。

文本格式的資料也是Hadoop中經常碰到的。如TextFile 、XML和JSON。 文本格式除了會占用更多磁盤資源外,對它的解析開銷一般會比二進制格式高幾十倍以上,尤其是XML 和JSON,它們的解析開銷比Textfile 還要大,是以強烈不建議在生産系統中使用這些格式進行儲存。 如果需要輸出這些格式,請在用戶端做相應的轉換操作。 文本格式經常會用于日志收集,資料庫導入,Hive預設配置也是使用文本格式,而且常常容易忘了壓縮,是以請確定使用了正确的格式。另外文本格式的一個缺點是它不具備類型和模式,比如銷售金額、利潤這類數值資料或者日期時間類型的資料,如果使用文本格式儲存,由于它們本身的字元串類型的長短不一,或者含有負數,導緻MR沒有辦法排序,是以往往需要将它們預處理成含有模式的二進制格式,這又導緻了不必要的預處理步驟的開銷和儲存資源的浪費。

1.TextFile

  • Hive資料表的預設格式,存儲方式:行存儲。
  • 可使用Gzip,Bzip2等壓縮算法壓縮,壓縮後的檔案不支援split
  • 但在反序列化過程中,必須逐個字元判斷是不是分隔符和行結束符,是以反序列化開銷會比SequenceFile高幾十倍。
--建立資料表:
create table if not exists textfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as textfile;
--插入資料:
set hive.exec.compress.output=true; --啟用壓縮格式 
set mapred.output.compress=true;    
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定輸出的壓縮格式為Gzip  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;      
insert overwrite table textfile_table select * from T_Name;      
Hive 檔案格式

2.SequenceFile

  • Hadoop API提供的一種二進制檔案,以<key,value>的形式序列化到檔案中。
  • 存儲方式:行存儲。
  • 支援三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮。
  • 這種二進制檔案内部使用Hadoop 的标準的Writable 接口實作序列化和反序列化。它與Hadoop API中的MapFile 是互相相容的,這是sequence file的一個優勢。
  • Hive 中的SequenceFile 繼承自Hadoop API 的SequenceFile,不過它的key為空,使用value 存放實際的值, 這樣是為了避免MR 在運作map 階段的排序過程。如果你用Java API 編寫SequenceFile,并讓Hive 讀取的話,請確定使用value字段存放資料,否則你需要自定義讀取這種SequenceFile 的InputFormat class 和OutputFormat class。 
  • SequenceFile是Hadoop本身就可以支援的一種标準檔案格式,因為它也是在Hive和其他Hadoop相關的工具中共享檔案的可以接受的選擇。而對于Hadoop生态系統之外的其它工具而言,其并不适用.
  • SequenceFile可以在塊級别和記錄級别進行壓縮,這對于優化磁盤使用率和I/0來說非常有意義。同時仍然可以支援按照塊級别的檔案進行分割,以友善并行處理。
值得注意的是,hive讀取sequencefile的時候,是把key忽略的,也就是直接讀value并且按照指定分隔符分隔字段。但是如果hive的資料來源是從mr生成的,那麼寫sequencefile的時候,key和value都是有意義的,key不能被忽略,而是應該當成第一個字段。為了解決這種不比對的情況,有兩種辦法。一種是要求凡是結果會給hive用的mr job輸出value的時候帶上key。但是這樣的話對于開發是一個負擔,讀寫資料的時候都要注意這個情況。是以更好的方法是第二種,也就是把這個源自于hive的問題交給hive解決,寫一個InputFormat包裝一下,把value輸出加上key即可。
create table if not exists seqfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as sequencefile;
--插入資料操作:
set hive.exec.compress.output=true;  --啟用輸出壓縮格式
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定輸出壓縮格式為Gzip
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
SET mapred.output.compression.type=BLOCK; --指定為Block
insert overwrite table seqfile_table select * from T_Name;      
Hive 檔案格式

3.RCFile

BG:大多數的Hadoop和Hive存儲都是行式存儲的,在大多數場景下,這是比較高效的。這種高效歸根于如下幾點:大多數的表具有的字段個數都不大(一般小于20個);對檔案按塊進行壓縮對于需要處理重複資料的情況比較高效,同時很多的處理和調試工具(如:more,head,awk)都可以很好的應用于行式存儲的資料。

并非所有的工具和資料存儲都是采用行式存儲的方式的,對于特定類型的資料和應用來說,采用列式存儲有時會更好。例如,如果指定的表具有成百上千個字段,而大多數的查詢隻需要使用到其中的一小部分字段,這是掃描所有的行而過濾掉大部分的資料顯然是個浪費。然而,如果資料是按照列而不是行進行存儲的話,那麼隻要對其需要的列進行掃描就可以了,這樣可以提高性能。

對于列式存儲而言,進行壓縮通常會非常高效,特别是在這列的資料具有較低計算的時候(隻有很少的排重值時)。同時,一些列式存儲并不需要無力存儲NULL值的列。

基于這些場景,HIVE中才設計了RCFile.

Hive功能強大的一個方面展現在不同的存儲格式間互相轉換資料非常的簡單。存儲資訊存放在了表的中繼資料資訊中。當對表執行一個select查詢時。以及向其他表中執行insert操作時,Hive就會使用這個表的中繼資料資訊中提供的内容,然後自動執行轉換過程。這樣使用可以有多種選擇,而不需要額外的程式來對不同的存儲格式進行轉換。

可以在建立表時使用:ColumnarSerDe, RCFileInputFormat 和 RCFileOutputFormat;  /(end bg)

存儲方式:資料按行分塊,每塊按列存儲。結合了行存儲和列存儲的優點:

  • 首先,RCFile 保證同一行的資料位于同一節點,是以元組重構的開銷很低
  • 其次,像列存儲一樣,RCFile 能夠利用列次元的資料壓縮,并且能跳過不必要的列讀取
  • RCFile是Hive推出的一種專門面向列的資料格式。 它遵循“先按列劃分,再垂直劃分”的設計理念。當查詢過程中,針對它并不關心的列時,它會在IO上跳過這些列。需要說明的是,RCFile在map階段從遠端拷貝仍然是拷貝整個資料塊,并且拷貝到本地目錄後RCFile并不是真正直接跳過不需要的列,并跳到需要讀取的列, 而是通過掃描每一個row group的頭部定義來實作的,但是在整個HDFS Block 級别的頭部并沒有定義每個列從哪個row group起始到哪個row group結束。是以在讀取所有列的情況下,RCFile的性能反而沒有SequenceFile高。

RCFile的一個行組包括三個部分:

  1.  第一部分是行組頭部的【同步辨別】,主要用于分隔 hdfs 塊中的兩個連續行組
  2.  第二部分是行組的【中繼資料頭部】,用于存儲行組單元的資訊,包括行組中的記錄數、每個列的位元組數、列中每個域的位元組數
  3.  第三部分是【表格資料段】,即實際的列存儲資料。在該部分中,同一列的所有域順序存儲。

     從圖可以看出,首先存儲了列 A 的所有域,然後存儲列 B 的所有域等。

Hive 檔案格式

資料追加:RCFile 不支援任意方式的資料寫操作,僅提供一種追加接口,這是因為底層的 HDFS目前僅僅支援資料追加寫檔案尾部。 

行組大小:行組變大有助于提高資料壓縮的效率,但是可能會損害資料的讀取性能,因為這樣增加了 Lazy 解壓性能的消耗。而且行組變大會占用更多的記憶體,這會影響并發執行的其他MR作業。 考慮到存儲空間和查詢效率兩個方面,Facebook 選擇 4MB 作為預設的行組大小,當然也允許使用者自行選擇參數進行配置。

create table if not exists rcfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as rcfile;
--插入資料操作:
set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
insert overwrite table rcfile_table select * from T_Name;      
Hive 檔案格式

4.ORCFile

相比傳統資料庫的行式存儲引擎,列式存儲引擎具有更高的壓縮比,更少的IO操作,尤其是在資料列很多,但每次操作僅針對若幹列進行查詢和計算的情景,列式存儲引擎的成本效益更高。目前在開源實作中,最有名的列式存儲引擎莫過于Parquet和ORC,并且他們都是Apache的頂級項目,在資料存儲引擎方面發揮着重要的作用。

  • 存儲方式:資料按行分塊 每塊按照列存儲
  • 壓縮快 快速列存取
  • 效率比rcfile高,是rcfile的改良版本

自定義格式

ORC(OptimizedRow Columnar) 檔案格式存儲源自于RC(RecordColumnar File)這種存儲格式,RC是一種列式存儲引擎,對schema演化(修改schema需要重新生成資料)支援較差,而ORC是對RC改進,但它仍對schema演化支援較差,主要是在壓縮編碼,查詢性能方面做了優化。RC/ORC最初是在Hive中得到使用,最後發展勢頭不錯,獨立成一個單獨的項目。Hive 1.x版本對事務和update操作的支援,便是基于ORC實作的(其他存儲格式暫不支援)。ORC發展到今天,已經具備一些非常進階的feature,比如支援update操作,支援ACID,支援struct,array複雜類型。你可以使用複雜類型建構一個類似于parquet的嵌套式資料架構,但當層數非常多時,寫起來非常麻煩和複雜,而parquet提供的schema表達方式更容易表示出多級嵌套的資料類型。

Hive中建立表時使用ORC資料存儲格式:

create table orc_table (id int,name string) stored as orc;

  • 使用者可以通過實作inputformat和 outputformat來自定義輸入輸出格式。
hive>  create table myfile_table(str STRING)  
    >  stored as  
    >  inputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat'  
    >  outputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextOutputFormat'; 
OK
Time taken: 0.399 seconds      
hive> load data local inpath '/root/hive/myfile_table'
    > overwrite into table myfile_table;--加載資料      
hive> dfs -text /user/hive/warehouse/myfile_table/myfile_table;--資料檔案内容,編碼後的格式
aGVsbG8saGl2ZQ==
aGVsbG8sd29ybGQ=
aGVsbG8saGFkb29w      
hive> select * from myfile_table;--使用自定義格式進行解碼
OK
hello,hive
hello,world
hello,hadoop
Time taken: 0.117 seconds, Fetched: 3 row(s)      

Parquet與ORC對比

Hive 檔案格式

5.Parquet列式存儲格式 (這部分完全轉至:http://www.infoq.com/cn/articles/in-depth-analysis-of-parquet-column-storage-format/)

Parquet是面向分析型業務的列式存儲格式,由Twitter和Cloudera合作開發,2015年5月從Apache的孵化器裡畢業成為Apache頂級項目,最新的版本是1.8.0。

列式存儲和行式存儲相比有哪些優勢呢?

  1. 可以跳過不符合條件的資料,隻讀取需要的資料,降低IO資料量。
  2. 壓縮編碼可以降低磁盤存儲空間。由于同一列的資料類型是一樣的,可以使用更高效的壓縮編碼(例如Run Length Encoding和Delta Encoding)進一步節約存儲空間。
  3. 隻讀取需要的列,支援向量運算,能夠擷取更好的掃描性能。

當時Twitter的日增資料量達到壓縮之後的100TB+,存儲在HDFS上,工程師會使用多種計算架構(例如MapReduce, Hive, Pig等)對這些資料做分析和挖掘;日志結構是複雜的嵌套資料類型,例如一個典型的日志的schema有87列,嵌套了7層。是以需要設計一種列式存儲格式,既能支援關系型資料(簡單資料類型),又能支援複雜的嵌套類型的資料,同時能夠适配多種資料處理架構。

關系型資料的列式存儲,可以将每一列的值直接排列下來,不用引入其他的概念,也不會丢失資料。關系型資料的列式存儲比較好了解,而嵌套類型資料的列存儲則會遇到一些麻煩。如圖1所示,我們把嵌套資料類型的一行叫做一個記錄(record),嵌套資料類型的特點是一個record中的column除了可以是Int, Long, String這樣的原語(primitive)類型以外,還可以是List, Map, Set這樣的複雜類型。在行式存儲中一行的多列是連續的寫在一起的,在列式存儲中資料按列分開存儲,例如可以隻讀取A.B.C這一列的資料而不去讀A.E和A.B.D,那麼如何根據讀取出來的各個列的資料重構出一行記錄呢?

Hive 檔案格式

圖1 行式存儲和列式存儲

Google的Dremel系統解決了這個問題,核心思想是使用“record shredding and assembly algorithm”來表示複雜的嵌套資料類型,同時輔以按列的高效壓縮和編碼技術,實作降低存儲空間,提高IO效率,降低上層應用延遲。Parquet就是基于Dremel的資料模型和算法實作的。

Parquet适配多種計算架構

Parquet是語言無關的,而且不與任何一種資料處理架構綁定在一起,适配多種語言群組件,能夠與Parquet配合的元件有:

查詢引擎: Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL

計算架構: MapReduce, Spark, Cascading, Crunch, Scalding, Kite

資料模型: Avro, Thrift, Protocol Buffers, POJOs

那麼Parquet是如何與這些元件協作的呢?這個可以通過圖2來說明。資料從記憶體到Parquet檔案或者反過來的過程主要由以下三個部分組成:

1, 存儲格式(storage format)

parquet-format項目定義了Parquet内部的資料類型、存儲格式等。

2, 對象模型轉換器(object model converters)

這部分功能由parquet-mr項目來實作,主要完成外部對象模型與Parquet内部資料類型的映射。

3, 對象模型(object models)

對象模型可以簡單了解為記憶體中的資料表示,Avro, Thrift, Protocol Buffers, Hive SerDe, Pig Tuple, Spark SQL InternalRow等這些都是對象模型。Parquet也提供了一個example object model 幫助大家了解。

例如parquet-mr項目裡的parquet-pig項目就是負責把記憶體中的Pig Tuple序列化并按列存儲成Parquet格式,以及反過來把Parquet檔案的資料反序列化成Pig Tuple。

這裡需要注意的是Avro, Thrift, Protocol Buffers都有他們自己的存儲格式,但是Parquet并沒有使用他們,而是使用了自己在parquet-format項目裡定義的存儲格式。是以如果你的應用使用了Avro等對象模型,這些資料序列化到磁盤還是使用的parquet-mr定義的轉換器把他們轉換成Parquet自己的存儲格式。

Hive 檔案格式

圖2 Parquet項目的結構

Parquet資料模型

了解Parquet首先要了解這個列存儲格式的資料模型。我們以一個下面這樣的schema和資料為例來說明這個問題。

message AddressBook {
 required string owner;
 repeated string ownerPhoneNumbers;
 repeated group contacts {
   required string name;
   optional string phoneNumber;
 }
}      

這個schema中每條記錄表示一個人的AddressBook。有且隻有一個owner,owner可以有0個或者多個ownerPhoneNumbers,owner可以有0個或者多個contacts。每個contact有且隻有一個name,這個contact的phoneNumber可有可無。這個schema可以用圖3的樹結構來表示。

每個schema的結構是這樣的:根叫做message,message包含多個fields。每個field包含三個屬性:repetition, type, name。repetition可以是以下三種:required(出現1次),optional(出現0次或者1次),repeated(出現0次或者多次)。type可以是一個group或者一個primitive類型。

Parquet格式的資料類型沒有複雜的Map, List, Set等,而是使用repeated fields 和 groups來表示。例如List和Set可以被表示成一個repeated field,Map可以表示成一個包含有key-value 對的repeated field,而且key是required的。

Hive 檔案格式
Hive 檔案格式

圖3 AddressBook的樹結構表示

Parquet檔案的存儲格式

那麼如何把記憶體中每個AddressBook對象按照列式存儲格式存儲下來呢?

在Parquet格式的存儲中,一個schema的樹結構有幾個葉子節點,實際的存儲中就會有多少column。例如上面這個schema的資料存儲實際上有四個column,如圖4所示。

Hive 檔案格式

圖4 AddressBook實際存儲的列

Parquet檔案在磁盤上的分布情況如圖5所示。所有的資料被水準切分成Row group,一個Row group包含這個Row group對應的區間内的所有列的column chunk。一個column chunk負責存儲某一列的資料,這些資料是這一列的Repetition levels, Definition levels和values(詳見後文)。一個column chunk是由Page組成的,Page是壓縮和編碼的單元,對資料模型來說是透明的。一個Parquet檔案最後是Footer,存儲了檔案的中繼資料資訊和統計資訊。Row group是資料讀寫時候的緩存單元,是以推薦設定較大的Row group進而帶來較大的并行度,當然也需要較大的記憶體空間作為代價。一般情況下推薦配置一個Row group大小1G,一個HDFS塊大小1G,一個HDFS檔案隻含有一個塊。

Hive 檔案格式

圖5 Parquet檔案格式在磁盤的分布

拿我們的這個schema為例,在任何一個Row group内,會順序存儲四個column chunk。這四個column都是string類型。這個時候Parquet就需要把記憶體中的AddressBook對象映射到四個string類型的column中。如果讀取磁盤上的4個column要能夠恢複出AddressBook對象。這就用到了我們前面提到的 “record shredding and assembly algorithm”。

Striping/Assembly算法

對于嵌套資料類型,我們除了存儲資料的value之外還需要兩個變量Repetition Level(R), Definition Level(D) 才能存儲其完整的資訊用于序列化和反序列化嵌套資料類型。Repetition Level和 Definition Level可以說是為了支援嵌套類型而設計的,但是它同樣适用于簡單資料類型。在Parquet中我們隻需定義和存儲schema的葉子節點所在列的Repetition Level和Definition Level。

Definition Level

嵌套資料類型的特點是有些field可以是空的,也就是沒有定義。如果一個field是定義的,那麼它的所有的父節點都是被定義的。從根節點開始周遊,當某一個field的路徑上的節點開始是空的時候我們記錄下目前的深度作為這個field的Definition Level。如果一個field的Definition Level等于這個field的最大Definition Level就說明這個field是有資料的。對于required類型的field必須是有定義的,是以這個Definition Level是不需要的。在關系型資料中,optional類型的field被編碼成0表示空和1表示非空(或者反之)。

Repetition Level

記錄該field的值是在哪一個深度上重複的。隻有repeated類型的field需要Repetition Level,optional 和 required類型的不需要。Repetition Level = 0 表示開始一個新的record。在關系型資料中,repetion level總是0。

下面用AddressBook的例子來說明Striping和assembly的過程。

對于每個column的最大的Repetion Level和 Definition Level如圖6所示。

Hive 檔案格式

圖6 AddressBook的Max Definition Level和Max Repetition Level

下面這樣兩條record:

AddressBook {
 owner: "Julien Le Dem",
 ownerPhoneNumbers: "555 123 4567",
 ownerPhoneNumbers: "555 666 1337",
 contacts: {
   name: "Dmitriy Ryaboy",
   phoneNumber: "555 987 6543",
 },
 contacts: {
   name: "Chris Aniszczyk"
 }
}
AddressBook {
 owner: "A. Nonymous"
}      

以contacts.phoneNumber這一列為例,"555 987 6543"這個contacts.phoneNumber的Definition Level是最大Definition Level=2。而如果一個contact沒有phoneNumber,那麼它的Definition Level就是1。如果連contact都沒有,那麼它的Definition Level就是0。

下面我們拿掉其他三個column隻看contacts.phoneNumber這個column,把上面的兩條record簡化成下面的樣子:

AddressBook {
 contacts: {
   phoneNumber: "555 987 6543"
 }
 contacts: {
 }
}
AddressBook {
}      

這兩條記錄的序列化過程如圖7所示:

Hive 檔案格式
Hive 檔案格式

圖7 一條記錄的序列化過程

如果我們要把這個column寫到磁盤上,磁盤上會寫入這樣的資料(圖8):

Hive 檔案格式

圖8 一條記錄的磁盤存儲

注意:NULL實際上不會被存儲,如果一個column value的Definition Level小于該column最大Definition Level的話,那麼就表示這是一個空值。

下面是從磁盤上讀取資料并反序列化成AddressBook對象的過程:

1,讀取第一個三元組R=0, D=2, Value=”555 987 6543”

R=0 表示是一個新的record,要根據schema建立一個新的nested record直到Definition Level=2。

D=2 說明Definition Level=Max Definition Level,那麼這個Value就是contacts.phoneNumber這一列的值,指派操作contacts.phoneNumber=”555 987 6543”。

2,讀取第二個三元組 R=1, D=1

R=1 表示不是一個新的record,是上一個record中一個新的contacts。

D=1 表示contacts定義了,但是contacts的下一個級别也就是phoneNumber沒有被定義,是以建立一個空的contacts。

3,讀取第三個三元組 R=0, D=0

R=0 表示一個新的record,根據schema建立一個新的nested record直到Definition Level=0,也就是建立一個AddressBook根節點。

可以看出在Parquet列式存儲中,對于一個schema的所有葉子節點會被當成column存儲,而且葉子節點一定是primitive類型的資料。對于這樣一個primitive類型的資料會衍生出三個sub columns (R, D, Value),也就是從邏輯上看除了資料本身以外會存儲大量的Definition Level和Repetition Level。那麼這些Definition Level和Repetition Level是否會帶來額外的存儲開銷呢?實際上這部分額外的存儲開銷是可以忽略的。因為對于一個schema來說level都是有上限的,而且非repeated類型的field不需要Repetition Level,required類型的field不需要Definition Level,也可以縮短這個上限。例如對于Twitter的7層嵌套的schema來說,隻需要3個bits就可以表示這兩個Level了。

對于存儲關系型的record,record中的元素都是非空的(NOT NULL in SQL)。Repetion Level和Definition Level都是0,是以這兩個sub column就完全不需要存儲了。是以在存儲非嵌套類型的時候,Parquet格式也是一樣高效的。

上面示範了一個column的寫入和重構,那麼在不同column之間是怎麼跳轉的呢,這裡用到了有限狀态機的知識,詳細介紹可以參考Dremel。

資料壓縮算法

列式存儲給資料壓縮也提供了更大的發揮空間,除了我們常見的snappy, gzip等壓縮方法以外,由于列式存儲同一列的資料類型是一緻的,是以可以使用更多的壓縮算法。

壓縮算法 使用場景
Run Length Encoding 重複資料
Delta Encoding 有序資料集,例如timestamp,自動生成的ID,以及監控的各種metrics
Dictionary Encoding 小規模的資料集合,例如IP位址
Prefix Encoding Delta Encoding for strings

性能

Parquet列式存儲帶來的性能上的提高在業内已經得到了充分的認可,特别是當你們的表非常寬(column非常多)的時候,Parquet無論在資源使用率還是性能上都優勢明顯。具體的性能名額詳見參考文檔。

Spark已經将Parquet設為預設的檔案存儲格式,Cloudera投入了很多工程師到Impala+Parquet相關開發中,Hive/Pig都原生支援Parquet。Parquet現在為Twitter至少節省了1/3的存儲空間,同時節省了大量的表掃描和反序列化的時間。這兩方面直接反應就是節約成本和提高性能。

如果說HDFS是大資料時代檔案系統的事實标準的話,Parquet就是大資料時代存儲格式的事實标準。

Apache Parquet 最初的設計動機是存儲嵌套式資料,比如Protocolbuffer,thrift,json等,将這類資料存儲成列式格式,以友善對其高效壓縮和編碼,且使用更少的IO操作取出需要的資料,這也是Parquet相比于ORC的優勢,它能夠透明地将Protobuf和thrift類型的資料進行列式存儲,在Protobuf和thrift被廣泛使用的今天,與parquet進行內建,是一件非容易和自然的事情。 除了上述優勢外,相比于ORC, Parquet沒有太多其他可圈可點的地方,比如它不支援update操作(資料寫成後不可修改),不支援ACID等。

6. Avro

Avro是一種用于支援資料密集型的二進制檔案格式。它的檔案格式更為緊湊,若要讀取大量資料時,Avro能夠提供更好的序列化和反序列化性能。并且Avro資料檔案天生是帶Schema定義的,是以它不需要開發者在API 級别實作自己的Writable對象。最近多個Hadoop 子項目都支援Avro資料格式,如Pig 、Hive、Flume、Sqoop和Hcatalog。

7.示例自定義輸入格式:DualInputFormat;

總結:

資料倉庫的特點:一次寫入、多次讀取,是以,整體來看,ORCFile相比其他格式具有較明顯的優勢。

  • TextFile 預設格式,加載速度最快,可以采用Gzip、bzip2等進行壓縮,壓縮後的檔案無法split,即并行處理
  • SequenceFile 壓縮率最低,查詢速度一般,三種壓縮格式NONE,RECORD,BLOCK
  • RCfile 壓縮率最高,查詢速度最快,資料加載最慢。

版權聲明:本文為CSDN部落客「weixin_34014277」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/weixin_34014277/article/details/92378615