此儲存庫包含用於讀取和寫入 Parquet 元資料的 Apache Parquet 和 Apache Thrift 定義的規格。
Apache Parquet 是一種開源、以列導向的資料檔案格式,專為高效資料儲存和檢索而設計。它提供高效能壓縮和編碼方案來批量處理複雜數據,並受到許多程式語言和分析工具的支援。
我們創建 Parquet 是為了讓 Hadoop 生態系統中的任何專案都能利用壓縮、高效的列式資料表示的優勢。
Parquet 是從頭開始建立的,考慮到了複雜的嵌套資料結構,並使用 Dremel 論文中描述的記錄粉碎和組裝演算法。我們相信這種方法優於嵌套名稱空間的簡單扁平化。
Parquet 旨在支援非常高效的壓縮和編碼方案。多個項目已經證明了對資料應用正確的壓縮和編碼方案對效能的影響。 Parquet 允許在每列層級指定壓縮方案,並且面向未來,允許在發明和實現時添加更多編碼。
Parquet 專為任何人使用而設計。 Hadoop生態系統有豐富的資料處理框架,我們不喜歡偏袒。我們相信,一個高效、實施良好的列式儲存底層應該對所有框架都有用,而無需付出大量且難以建立依賴關係的成本。
parquet-format
專案包含正確讀取 Parquet 檔案所需的格式規格和 Thrift 元資料定義。
parquet-java
專案包含多個子模組,它們實現了讀寫嵌套的、面向列的資料流的核心元件,將該核心映射到parquet格式,並提供Hadoop輸入/輸出格式、Pig載入器等用於與Parquet 互動的基於java 的實用程式。
parquet-compatibility
專案包含相容性測試,可用於驗證不同語言的實作是否可以讀取和寫入彼此的檔案。
可以使用mvn package
建構 Java 資源。目前的穩定版本應該始終可以從 Maven Central 獲得。
C++ Thrift 資源可以透過 make 產生。
Thrift 還可以將程式碼產生為任何其他 Thrift 支援的語言。
區塊(HDFS區塊):這意味著HDFS中的區塊,並且對於描述這種檔案格式的含義沒有改變。該檔案格式旨在在 HDFS 上運作良好。
文件:HDFS 文件,必須包含文件的元資料。它不需要實際包含數據。
行組:將資料邏輯水平劃分為行。行組沒有保證的實體結構。行組由資料集中每列的列區塊組成。
列塊:特定列的資料塊。它們位於特定的行組中,並保證在文件中是連續的。
頁:列塊被分成頁。頁面在概念上是一個不可分割的單元(就壓縮和編碼而言)。列區塊中可以有多種交錯的頁面類型。
從層次結構來看,檔案由一個或多個行組組成。行組的每列恰好包含一個列塊。列塊包含一頁或多頁。
應同時閱讀該文件和 Thrift 定義以了解其格式。
4-byte magic number "PAR1"
<Column 1 Chunk 1>
<Column 2 Chunk 1>
...
<Column N Chunk 1>
<Column 1 Chunk 2>
<Column 2 Chunk 2>
...
<Column N Chunk 2>
...
<Column 1 Chunk M>
<Column 2 Chunk M>
...
<Column N Chunk M>
File Metadata
4-byte length in bytes of file metadata (little endian)
4-byte magic number "PAR1"
在上面的範例中,該表中有 N 列,分為 M 行組。文件元資料包含所有列塊起始位置的位置。有關元資料中包含的內容的更多詳細資訊可以在 Thrift 定義中找到。
文件元資料在資料之後寫入,以允許單遍寫入。
讀者應首先讀取文件元數據以找到他們感興趣的所有列塊。
元資料有兩種類型:文件元資料和頁首元資料。所有 thrift 結構都使用 TCompactProtocol 進行序列化。
檔案格式支援的類型盡可能少,重點放在類型對磁碟儲存的影響。例如,儲存格式未明確支援 16 位元整數,因為它們被具有高效編碼的 32 位元整數覆蓋。這降低了實現該格式的讀取器和寫入器的複雜性。類型有:
邏輯類型用於透過指定應如何解釋基本類型來擴展 parquet 可用於儲存的類型。這將原始類型集保持在最低限度,並重複使用 parquet 的高效編碼。例如,字串以帶有 STRING 註解的基本類型 BYTE_ARRAY 儲存。這些註釋定義瞭如何進一步解碼和解釋數據。註解作為LogicalType
欄位儲存在檔案元資料中,並記錄在 LogicalTypes.md 中。
Parquet 在多個層級(例如列區塊、列索引和資料頁)儲存最小/最大統計資料。類型值的比較遵循以下規則:
每個邏輯類型都有指定的比較順序。如果列以未知的邏輯類型註釋,則統計資訊可能無法用於修剪資料。邏輯類型的排序順序記錄在 LogicalTypes.md 頁面中。
對於原始類型,適用以下規則:
布林值 - 假、真
INT32、INT64 - 有符號比較。
FLOAT、DOUBLE - 對 NaN 和有符號零進行特殊處理的有符號比較。詳細資訊記錄在ColumnOrder
聯合的 Thrift 定義中。這裡對其進行了總結,但 Thrift 定義被認為是權威性的:
+0.0
寫入最大統計欄位。-0.0
寫入最小值統計欄位。為了在讀取文件時向後相容:
BYTE_ARRAY 和 FIXED_LEN_BYTE_ARRAY - 字典順序無符號位元組比較。
為了對嵌套列進行編碼,Parquet 使用具有定義和重複層級的 Dremel 編碼。定義層級指定在列的路徑中定義了多少個可選欄位。重複等級指定路徑中的哪個重複欄位具有重複值。最大定義和重複層級可以根據模式計算(即有多少嵌套)。這定義了儲存層級所需的最大位數(層級是為列中的所有值定義的)。
支援 BIT_PACKED 和 RLE 兩種等級編碼。現在只使用 RLE,因為它取代了 BIT_PACKED。
空值在定義層級中進行編碼(遊程編碼)。 NULL 值不會編碼在資料中。例如,在非嵌套模式中,具有 1000 個 NULL 的欄位將使用遊程長度編碼(0、1000 次)針對定義層級進行編碼,而不進行其他處理。
對於資料頁,這 3 個訊息在頁首之後被背對背編碼。資料頁中不允許填入。為了我們有:
標頭中指定的uncompressed_page_size
值適用於所有 3 個部分的組合。
資料頁的編碼值始終是必需的。根據模式定義,定義和重複等級是可選的。如果列不是嵌套的(即列的路徑長度為 1),我們不會對重複層級進行編碼(它將始終具有值 1)。對於所需的數據,將跳過定義層級(如果進行編碼,它將始終具有最大定義層級的值)。
例如,在列非嵌套且需要的情況下,頁面中的資料只是編碼值。
Encodings.md 中描述了支援的編碼
Compression.md 中描述了支援的壓縮編解碼器
列塊由背對背寫入的頁組成。這些頁面共享一個公共標題,讀者可以跳過他們不感興趣的頁面。壓縮和編碼在頁面元資料中指定。
列塊可能部分或完全是字典編碼的。這意味著字典索引保存在資料頁中,而不是實際值。實際值儲存在字典頁中。請參閱 Encodings.md 中的詳細資訊。字典頁必須放置在列塊的第一個位置。一個列區塊中最多可以放置一個字典頁。
此外,文件可以包含可選的列索引,以允許讀者更有效地跳過頁面。有關詳細資訊以及將這些新增至格式背後的原因,請參閱 PageIndex.md。
各種頁面都可以單獨進行校驗和。這允許在 HDFS 檔案層級停用校驗和,以更好地支援單行查找。校驗和是使用標準 CRC32 演算法(例如 GZip 中使用的)對頁面的序列化二進位表示形式(不包括頁面標頭本身)進行計算的。
如果檔案元資料損壞,檔案就會遺失。如果列元資料損壞,則該列區塊會遺失(但其他行組中該列的列區塊沒有問題)。如果頁頭損壞,則該區塊中的剩餘頁將遺失。如果頁面內的資料損壞,該頁面就會遺失。對於較小的行組,檔案將更能抵抗損壞。
潛在的擴展:對於較小的行組,最大的問題是將文件元資料放在末尾。如果寫入文件元資料時發生錯誤,則寫入的所有資料將不可讀。這可以透過每隔 N 行組寫入檔案元資料來解決。每個文件元資料都是累積的,並包括迄今為止寫入的所有行組。將此與使用同步標記的 rc 或 avro 檔案所使用的策略結合,讀取器可以恢復部分寫入的檔案。
此格式明確設計用於將元資料與資料分開。這允許將列拆分為多個文件,以及讓單一元資料文件引用多個 parquet 文件。
格式中有很多地方可以兼容擴充:
Parquet Thrift IDL 保留每個 Thrift 結構的欄位 ID 32767
用於擴充。該欄位的 (Thrift) 類型始終是binary
。
apache/parquet-testing 包含一組用於測試目的的 Parquet 檔案。
對問題發表評論和/或聯絡 parquet-dev 郵件列表,提出您的問題和想法。對此核心格式定義的變更在郵件清單上提出並進行了深入討論。您可能也有興趣為 Parquet-Java 子專案做出貢獻,其中包含所有 Java 端實作和 API。請參閱 Parquet-Java 專案的「如何貢獻」部分
我們要求自己和 Parquet 開發者社群遵守 Twitter OSS 所描述的行為準則:https://github.com/twitter/code-of-conduct/blob/master/code-of-conduct.md。
版權所有 2013 Twitter、Cloudera 和其他貢獻者。
根據 Apache 授權 2.0 版授權:http://www.apache.org/licenses/LICENSE-2.0