Parquet
Apache Parquet is a columnar storage format available to any project in the Hadoop ecosystem, regardless of the choice of data processing framework, data model or programming language.
一、整體介紹 來自大資料技術架構的原文
Parquet 是一種支援嵌套結構的列式存儲格式 非常适用于 OLAP 場景,按列存儲和掃描
諸如 Parquet 這種列存的特點或優勢主要展現在兩方面:
1、更高的壓縮比
列存使得更容易對每個列使用高效的壓縮和編碼,降低磁盤空間。(網上的case是不壓縮、gzip、snappy分别能達到11/27/19的壓縮比)
2、更小的IO操作
使用映射下推和謂詞下推,隻讀取需要的列,跳過不滿足條件的列,能夠減少不必要的資料掃描,帶來性能的提升并在表字段比較多的時候更加明顯。
關于映射下推與謂詞下推:
**映射下推,**這是列式存儲最突出的優勢,是指在擷取資料時隻需要掃描需要的列,不用全部掃描。
**謂詞下推,**是指通過将一些過濾條件盡可能的在最底層執行以減少結果集。謂詞就是指這些過濾條件,即傳回bool:true和false的表達式,比如SQL中的大于小于等于、Like、Is
Null等。
Parquet 是與語言無關的,而且不與任何一種資料處理架構綁定在一起,後面詳述。
二、項目概述 來自大資料技術架構的原文
Parquet 是與語言無關的,而且不與任何一種資料處理架構綁定在一起,适配多種語言群組件,能夠與 Parquet 适配的查詢引擎包括 Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL等,計算架構包括 MapReduce, Spark, Cascading, Crunch, Scalding, Kite 等,資料模型包括 Avro, Thrift, Protocol Buffer, POJOs 等。
Parquet 的項目組成及自下而上互動的方式如圖所示:
這裡可以将其分為三層。
資料存儲層:定義 Parquet 檔案格式,其中中繼資料在 parquet-format 項目中定義,包括 Parquet 原始類型定義、Page類型、編碼類型、壓縮類型等等。
對象轉換層:這一層在 parquet-mr 項目中,包含多個子產品,作用是完成其他對象模型與 Parquet 内部資料模型的映射和轉換,Parquet 的編碼方式使用的是 striping and assembly 算法。
對象模型層:定義如何讀取 Parquet 檔案的内容,這一層轉換包括 Avro、Thrift、Protocal Buffer 等對象模型/序列化格式、Hive serde 等的适配。并且為了幫助大家了解和使用,Parquet 提供了 org.apache.parquet.example 包實作了 java 對象和 Parquet 檔案的轉換。
其中,對象模型可以簡單了解為記憶體中的資料表示,Avro, Thrift, Protocol Buffer, Pig Tuple, Hive SerDe 等這些都是對象模型。例如 parquet-mr 項目裡的 parquet-pig 項目就是負責把記憶體中的 Pig Tuple 序列化并按列存儲成 Parquet 格式,以及反過來把 Parquet 檔案的資料反序列化成 Pig Tuple。
這裡需要注意的是 Avro, Thrift, Protocol Buffer 等都有他們自己的存儲格式,但是 Parquet 并沒有使用他們,而是使用了自己在 parquet-format 項目裡定義的存儲格式。是以如果你的項目使用了 Avro 等對象模型,這些資料序列化到磁盤還是使用的 parquet-mr 定義的轉換器把他們轉換成 Parquet 自己的存儲格式。
三、 支援嵌套的資料模型 來自大資料技術架構的原文
Parquet 支援嵌套結構的資料模型,而非扁平式的資料模型,這是 Parquet 相對其他列存比如 ORC 的一大特點或優勢。支援嵌套式結構,意味着 Parquet 能夠很好的将諸如 Protobuf,thrift,json 等對象模型進行列式存儲。
Parquet 的資料模型也是 schema 表達方式,用關鍵字 message 表示。每個字段包含三個屬性,repetition屬性(required/repeated/optional)、資料類型(primitive基本類型/group複雜類型)及字段名。
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 可以用下面的樹結構來表示。
Parquet 格式的資料類型沒有複雜的 Map, List, Set 等,而是使用 repeated fields 和 groups 來表示。例如 List 和 Set 可以被表示成一個 repeated field,Map 可以表示成一個包含有 key-value 對的 repeated field,而且 key 是 required 的。
四、存儲模型 來自大資料技術架構的原文
這裡存儲模型又可以了解為存儲格式或檔案格式,Parquet 的存儲模型主要由行組(Row Group)、列塊(Column Chuck)、頁(Page)組成。
**1、行組,Row Group:**Parquet 在水準方向上将資料劃分為行組,預設行組大小與 HDFS Block 塊大小對齊,Parquet 保證一個行組會被一個 Mapper 處理。
**2、列塊,Column Chunk:**行組中每一列儲存在一個列塊中,一個列塊具有相同的資料類型,不同的列塊可以使用不同的壓縮。
**3、頁,Page:**Parquet 是頁存儲方式,每一個列塊包含多個頁,一個頁是最小的編碼的機關,同一列塊的不同頁可以使用不同的編碼方式。
另外 Parquet 檔案還包含header與footer資訊,分别存儲檔案的校驗碼與Schema等資訊。參考官網的一張圖:
五、 Parquet vs ORC
除了 Parquet,另一個常見的列式存儲格式是 ORC(OptimizedRC File)。在 ORC 之前,Apache Hive 中就有一種列式存儲格式稱為 RCFile(RecordColumnar File),ORC 是對 RCFile 格式的改進,主要在壓縮編碼、查詢性能方面做了優化。是以 ORC/RC 都源于 Hive,主要用來提高 Hive 查詢速度和降低 Hadoop 的資料存儲空間。
Parquet 與 ORC 的不同點總結以下:
嵌套結構支援: Parquet 能夠很完美的支援嵌套式結構,而在這一點上 ORC 支援的并不好,表達起來複雜且性能和空間都損耗較大。
更新與 ACID 支援:ORC 格式支援 update 操作與 ACID,而 Parquet 并不支援。
壓縮與查詢性能:在壓縮空間與查詢性能方面,Parquet 與 ORC 總體上相差不大。可能 ORC 要稍好于 Parquet。
查詢引擎支援:這方面 Parquet 可能更有優勢,支援 Hive、Impala、Presto 等各種查詢引擎,而 ORC 與 Hive 接觸的比較緊密,而與 Impala 适配的并不好。之前我們說 Impala 不支援 ORC,直到 CDH 6.1.x 版本也就是 Impala3.x 才開始以 experimental feature 支援 ORC 格式。