Hive 存儲格式

摘錄自《Hadoop 權威指南》

Hive 從兩個維度對錶的存儲進行管理,分別是行格式(row format)和文件格式(file format)。行格式指行和一行中的字段如何存儲。按照 Hive 的術語,行格式的定義由 SerDe 定義。SerDe 是“序列化和反序列化工具”(Serializer-Deserialize)的合成詞。

當作爲反序列化工具進行使用時,也就是查詢表時,SerDe 將把文件中字節形式的數據行反序列化爲 Hive 內部操作數據行時使用的對象形式。使用序列化工具時,也就是執行 INSERT 或 CTAS(CREATE TABLE … AS SELECT)時,表的 SerDe 會把 Hive 的數據行內部表示形式序列化成字節形式並寫到輸出文件中。

文件格式指一行字段容器的格式,最簡單的格式是純文本文件,但是也可以使用面向行的和麪向列的二進制格式。

1. 默認存儲格式:分割的文本

如果在創建表沒有用 ROW FORMAT 或 STORED AS 子句,那麼 Hive 所使用的默認格式是分隔的文本,每行(line)存儲一個數據行(row)。

默認的行內分隔符不是製表符,而是 ASCII 控制碼集合中的 Control-A(它的 ASCII 碼爲 1)。選擇 Control-A(在文檔中有時記作 ^A )作爲分隔符是因爲和製表符相比,它出現在字段文本中的可能性比較小。在 Hive 中無法對分隔符進行轉義,因此,挑選一個不會在數據字段中用到的字符作爲分隔符非常重要。

集合類元素的默認分隔符爲字符 Control-B。它用於分隔 ARRAY 或 STRUCT 或 MAP 的鍵-值對中的元素。默認的映射鍵(map key)分隔符爲字符 Control-C。它用於分隔 MAP 的鍵和值。表中各行之間用換行符分隔。

前面對分隔符的描述,對於一般情況下的平面數據結構——即只包含原子數據類型的複雜數據類型——都是沒問題的。但是,對於嵌套數據類型,這還不夠。事實上,嵌套的層次(level)決定了使用哪種分隔符。
例如,對於數組的數組,外層數據的分隔符如前所述是 Control-B 字符,但內層數據則使用分隔符列表中的下一項(Control-C 字符)作爲分隔符。如果不確定 Hive 使用哪個字符作爲某個嵌套結構的分隔符,可以運行以下命令:

CREATE TABLE nested
AS
SELECT array(array(1, 2), array(3, 4))
FROM dummy;

然後再使用 hexdump 或類似的命令查看輸出文件的分隔符。
實際上,Hive 支持 8 級分隔符,分別對應於 ASCII 編碼的 1,2,……,8。但是隻能重載其中的前三個。

因此,以下語句:

CREATE TABLE ...;

等價於下面顯示說明的語句:’

CREATE TABLE ...
ROW FORMAT DELIMITED
 FIELDS TERMINATED BY '\001'
 COLLECTION ITEMS TERMINATED BY '\002'
 MAP KEYS TERMINATED BY '\003'
 LINES TERMINATED BY '\n'
STORED AS TEXTFILE; 

注意,可以使用八進制形式表示分隔符,例如,001 表示 Control-A。

Hive 在內部使用一個名爲 LazySimpleSerDe 的 SerDe 來處理這種分隔符格式以及面向行的 MapReduce 文本輸入和輸出格式。這裏使用前綴“lazy”的原因是這個 SerDe 對字段的反序列化是延遲處理的,只有在訪問字段時纔會反序列化。但是,由於文本以冗餘的形式進行存放,所以這種存儲格式並不緊湊。比如,一個布爾值事實上是以文本字符串 true 或 false 的形式存放的。

這種簡單的格式有很多好處,例如,使用其它工具(包括 MapReduce 程序或 Streaming)來處理這樣的格式非常容易。但是還可以選擇一些更緊湊和高效的二進制 SerDe。

2. 二進制存儲格式:順序文件、Avro 數據文件、Parquet 文件、RCFile 與 ORCFile

二進制格式的使用方法非常簡單,只需要通過 CREATE TABLE 語句中的 STORED AS 子句做相應聲明。這裏不需要指定 ROW FORMAT,因爲其格式由底層的二進制文件格式來控制。

二進制格式可分爲兩大類:面向行的格式和麪向列的格式。一般來說,

  • 面向列的存儲格式對於那些只訪問表中一小部分列的查詢比較有效;
  • 相反,面向行的存儲格式適合同時處理一行中很多列的情況;

Hive 本身支持兩種面向行的格式:Avro 數據文件和順序文件,它們都是通用的可分割、可壓縮的格式。另外,Avro 還支持模式演化以及多種編程語言的綁定。在 Hive 0.14.0 之後版本中,使用下述語句可以將表存儲爲 Avro 格式:

SET hive.exec.compress.output=true;
SET avro.output.codec=snappy;
CREATE TABLE ... STORED AS AVRO;

請注意,通過設置相應的屬性即可支持表壓縮。

類似地,Hive 利用 CREATE TABLE 語句中的 STORED AS SEQUNCEFILE 子句聲明,將順序文件作爲存儲格式。Hadoop 壓縮

Hive 本身可支持的面向列的格式包括:Parquet、RECFile 和 ORCFile。下面這個示例使用 CREATE TABLE … AS SELECT 語句來創建一個表的 parquet 格式的複本。

CREATE TABLE users_parquet STORED AS PARQUET
AS
SELECT * FROM users;

3. 使用定製的 SerDe:RegexSerDe

CREATE TABLE table_name
...
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WIHT SERDEPROPERTIES ("input.regex" = "(\\d{6})(\\d{5}(.{29})).*")
;

SerDe 可以用 WITH SERDEPROPERTIES 子句來設置額外的屬性。上面設置 RegexSerDe 特有的 input.regex 屬性。

4. 存儲句柄

存儲句柄(Storage handler)用於 Hive 自身無法訪問的存儲系統,比如 HBase。存儲句柄使用 STORED BY 子句指定。它代替了 ROW FORMAT 和 STORED AS 子句。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章