參考文章:parquet 簡介
簡介
Apache Parquet是一種能夠有效存儲嵌套數據的列式存儲格式。
面向分析型業務的列式存儲格式
由 Twitter 和 Cloudera 合作開發,2015 年 5 月從 Apache 的孵化器裏畢業成爲 Apache 頂級項目。
Parquet源碼 : https://github.com/apache/parquet-mr
Parquet的設計目標:
- 適配通用性
- 存儲空間優化
- 計算時間優化
Parquet的原子類型:
Parquet的邏輯類型:
Parquet文件的內部結構:
Parquet文件由一個文件頭(header),一個或多個緊隨其後的文件塊(block),以及一個用於結尾的文件尾(footer)構成。文件頭僅包含
Parquet文件的每個文件塊負責存儲一個行組,行組由列塊組成,且一個列塊負責存儲一列數據。每個列塊中的的數據以頁爲單位。
列式存儲
概念:傳統的思維中是按照一條記錄一條記錄的組織存儲,列式存儲是豎過來,按照一列一列的方式組織存儲。
每次查詢數據只針對其中的少數幾個字段,這時候列式存儲是極佳的選擇。
列式存儲要解決的問題:
- 把IO只給查詢需要用到的數據
- 只加載需要被計算的列
- 空間節省
- 列式的壓縮效果更好
- 可以針對數據類型進行編碼
- 開啓矢量化的執行引擎(不再1條1條的處理數據,而是一次處理1024條數據)
列式存儲和行式存儲相比的優勢:
- 可以跳過不符合條件的數據,只讀取需要的數據,降低 IO 數據量。
- 壓縮編碼可以降低磁盤存儲空間。由於同一列的數據類型是一樣的,可以使用更高效的壓縮編碼(例如 Run Length Encoding 和 Delta Encoding)進一步節約存儲空間。
- 只讀取需要的列,支持向量運算,能夠獲取更好的掃描性能。
當時 Twitter 的日增數據量達到壓縮之後的 100TB+,存儲在 HDFS 上,工程師會使用多種計算框架(例如 MapReduce, Hive, Pig 等)對這些數據做分析和挖掘;
日誌結構是複雜的嵌套數據類型,例如一個典型的日誌的 schema 有 87 列,嵌套了 7 層。所以需要設計一種列式存儲格式,既能支持關係型數據(簡單數據類型),又能支持複雜的嵌套類型的數據,同時能夠適配多種數據處理框架。
關係型數據的列式存儲,可以將每一列的值直接排列下來,不用引入其他的概念,也不會丟失數據。
適配通用性
Parquet只是一種存儲格式,它與上層平臺、語言無關,不需要與任何一種數據處理框架綁定,目前已經適配的組件包括:
- 查詢引擎:Hive\Impala\Pig\Presto\Drill\Tajo\HAWQ\IBM Big SQL
- 計算引擎:MapReduce\Spark\Cascading\Crunch\Scalding\Kite
- 數據模型:Avro\Thrift\Protocol Buffers
Parquet的數據模型
每條記錄中的字段可以包含三種類型:required, repeated, optional。最終由所有葉子節點來代表整個schema。
- 元組的Schema可以轉換成樹狀結構,根節點可以理解爲repeated類型
- 所有葉子結點都是基本類型
- 沒有Map、Array這樣的複雜數據結構,但是可以通過repeated和group組合來實現這樣的需求
Parquet文件格式
Parquet文件是二進制方式存儲的,文件中包含數據和元數據,可以直接進行解析。
先了解一下關於Parquet文件的幾個基本概念:
- 行組(Row Group):每一個行組包含一定的行數,一般對應一個HDFS文件塊,Parquet讀寫的時候會將整個行組緩存在內存中。
- 列塊(Column Chunk):在一個行組中每一列保存在一個列塊中,一個列塊中的值都是相同類型的,不同的列塊可能使用不同的算法進行壓縮。
- 頁(Page):每一個列塊劃分爲多個頁,一個頁是最小的編碼的單位,在同一個列塊的不同頁可能使用不同的編碼方式。
Parquet文件組成:
- 文件開始和結束的4個字節都是Magic Code,用於校驗它是否是一個Parquet文件
- 結束MagicCode前的Footer length是文件元數據的大小,通過該值和文件長度可以計算出元數據Footer的偏移量
-
再往前推是Footer文件的元數據,裏面包含:
- 文件級別的信息:版本,Schema,Extra key/value對等
- 每個行組的元信息,每個行組是由多個列塊組成的:
- 每個列塊的元信息:類型,路徑,編碼方式,第1個數據頁的位置,第1個索引頁的位置,壓縮的、未壓縮的尺寸,額外的KV
-
文件中大部分內容是各個行組信息:
- 一個行組由多個列塊組成
- 一個列塊由多個頁組成,在Parquet中有三種頁:
- 數據頁
- 一個頁由頁頭、repetition levels\definition levles\valus組成
- 字典頁
- 存儲該列值的編碼字典,每一個列塊中最多包含一個字典頁
- 索引頁
- 用來存儲當前行組下該列的索引,目前Parquet中還不支持索引頁,但是在後面的版本中增加
- 數據頁
- 一個列塊由多個頁組成,在Parquet中有三種頁:
- 一個行組由多個列塊組成
Parquet 適配多種計算框架
Parquet 是語言無關的,
而且不與任何一種數據處理框架綁定在一起,
適配多種語言和組件,能夠與 Parquet 配合的組件有:
- 查詢引擎: Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL
- 計算框架: MapReduce, Spark, Cascading, Crunch, Scalding, Kite
- 數據模型: Avro, Thrift, Protocol Buffers, POJOs