(譯)優化ORC和Parquet檔案,提升大SQL讀取效能
簡介
眾所周知,多個Hadoop
小檔案(定義為明顯小於HDFS
塊大小的檔案,預設情況下為64MB
)是Hadoop
分散式檔案系統(HDFS
)中的一個大問題。HDFS
旨在儲存大量資料,理想情況下以大檔案的形式儲存。在HDFS
中儲存大量小檔案,而不是儲存較少的大檔案,這在管理檔案的目錄樹時給NameNode
增加了額外的開銷。此外,MapReduce
和其他讀取HDFS
檔案的作業也會受到負面影響,因為它將涉及與HDFS
的更多通訊以獲取檔案資訊。
小檔案讀取效能問題對於儲存格式更為嚴重,在儲存格式中,元資料被嵌入檔案中以描述所儲存的複雜內容。IBM Db2 Big SQL使用的兩種常見檔案儲存格式是ORC
Parquet
,這些檔案格式以列格式儲存資料,以優化讀取和過濾列的子集。ORC
和Parquet
格式將有關列和行組的資訊編碼到檔案本身中,因此,在對檔案中的資料進行解壓縮、反序列化和讀取之前,需要處理元資料。由於這種開銷,處理以邏輯方式捆綁在一起的這些格式的多個小型檔案(例如,屬於Big SQL
表或分割槽的檔案)會產生大量成本,並降低IBM Db2 Big SQL
的讀取效能。
建議解決方案:壓縮
避免在儲存級別使用小檔案的一個好習慣是對邏輯上屬於一起的目錄裡的小檔案進行壓縮。在Big SQL
中,屬於同一表的檔案通常儲存在同一目錄中。IBM Db2 Big SQL
的“檔案檢查工具”有助於識別HDFS
HDFS
塊對齊,有助於提高Big SQL
讀取效能。
ORC
和Parquet
提供了它們自己的不同工具來進行檔案合併或壓縮:
ORC
使用HIVE DDL
Parquet
使用工具執行合併命令
ORC檔案合併
使用Hive DDL
(Hive Data Definition Language
),使用者可以通過在表或分割槽上執行concatenate
命令來有效地合併小檔案為更大的檔案,命令如下:
ALTER TABLE table_name [PARTITION (partition_key = 'partition_value')] CONCATENATE;
Hive
會在stripe
級別合併ORC
檔案來降低資料壓縮/解壓和編解碼的開銷。
Parquet檔案合併
作為Apache Parquet
專案的一部分,有一組基於Java
的命令列工具,稱為parquet-tools
。最新的parquet-tools版本包括一個merge命令,該命令可以將較小的parquet
檔案邏輯地追加到較大的parquet
檔案中。該命令以二進位制形式將parquet
檔案塊串聯在一起,而無需序列化/反序列化、合併頁尾、修改路徑和偏移量元資料。
要在HDFS
中執行parquet-tools merge
命令:
hadoop jar parquet-tools-1.9.0.jar merge <input> <output>
其中,input
是源parquet
檔案或目錄,而output
是合併原始內容的目標parquet
檔案,此合併命令不會刪除或覆蓋原始檔案。因此,它需要手動建立一個臨時目錄,並用壓縮後的檔案替換原始的小檔案,以使Big SQL
或Apache Hive
知道該檔案。
另外,不管檔案的儲存格式如何,要考慮的解決方案是重新建立表並通過執行INSERT…SELECT
進行壓縮。
使用INSERT…SELECT合併檔案
通過使用INSERT…SELECT
語法直接建立一個新表作為原始表的副本來壓縮效率低下的拆分資料,此過程將根據插入的並行度將資料重新組織為相對少量的較大檔案。
以下是一個如何建立新表,然後在Big SQL
中插入舊錶中的資料的示例:
CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table select * from old_table;
該解決方案還允許通過將資料分割槽複製到新表中,刪除原始分割槽並插入新的壓縮分割槽來合併單個分割槽中的檔案。
最後,如果需要保留小檔案以供記錄,建議使用Hadoop
存檔資源(Hadoop Archive Resources (har))對其進行存檔,降低NameNode
管理大量資源和物件的成本。
效能改進
內部測試表明,壓縮ORC
和Parquet
小檔案有助於顯著提高Big SQL
的讀取效能。
針對ORC
和Parquet
格式進行測試的方案包括:
一百萬行表以兩種方式儲存:
HDFS
中30個大小不一的非最佳小檔案HDFS
中的2個壓縮大檔案,是根據檔案格式使用parquet tools
或Hive DDL
合併的小檔案的結果
執行一個查詢,計算一個數字列的總和,以通過訪問所有列內容來給整個表施加壓力:
SELECT SUM(column_name) FROM table_name;
結果表明:
- 在
ORC
格式的非壓縮表執行查詢比在壓縮表上執行查詢多2倍的時間 - 在
parquet
格式的非壓縮表執行查詢比在壓縮表上執行查詢多1.6倍的時間
這是針對ORC
檔案格式的壓縮測試的輸出,其中SLS_SALES_FACT_ORC
是非壓縮表,而SLS_SALES_FACT_COMPACTED_ORC
是在非壓縮表上執行CONCATENATE
命令的表結果:
[host][bigsql] 1> SELECT COUNT(*) FROM GOSALESDW.SLS_SALES_FACT_ORC;
+---------+
| 1 |
+---------+
| 1000000 |
+---------+
1 row in results(first row: 0.393s; total: 0.395s)
[host][bigsql] 1> SELECT SUM(GROSS_PROFIT) FROM GOSALESDW.SLS_SALES_FACT_ORC;
WARN [State: 01003][Code: 0]: Statement processing was successful.. SQLCODE=0, SQLSTATE=01003, DRIVER=3.72.24
+------------------+
| 1 |
+------------------+
| 4615167406.55999 |
+------------------+
1 row in results(total: 7.681s)
[bigsql@host root]$ hdfs dfs -ls /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc
Found 30 items
drwxrwxrwx - bigsql hadoop 0 2017-12-14 17:54 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/._biginsights_stats
-rw-r--r-- 3 bigsql hadoop 443027 2017-12-14 17:53 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-307213540_201712140553882_1.1
-rw-r--r-- 3 bigsql hadoop 179411 2017-12-14 17:53 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-307213540_201712140553882_1.2
-rw-r--r-- 3 bigsql hadoop 897796 2017-12-14 17:49 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-412191103_201712140549330_1.1
-rw-r--r-- 3 bigsql hadoop 1176528 2017-12-14 17:49 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-412191103_201712140549330_1.2
-rw-r--r-- 3 bigsql hadoop 3356 2017-12-14 17:59 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-710448882_201712140559369_1.1
...
-rw-r--r-- 3 bigsql hadoop 52854 2017-12-14 18:09 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_-451786036_201712140609603_2.2
-rw-r--r-- 3 bigsql hadoop 435203 2017-12-14 18:09 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_215889957_201712140609092_1.1
-rw-r--r-- 3 bigsql hadoop 1218285 2017-12-14 18:09 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_215889957_201712140609092_1.2
-rw-r--r-- 3 bigsql hadoop 2112684 2017-12-14 17:51 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_orc/i_1512166475533_866891040_201712140551232_2.2
[host][bigsql] 1> SELECT COUNT(*) FROM GOSALESDW.SLS_SALES_FACT_COMPACTED_ORC;
+---------+
| 1 |
+---------+
| 1000000 |
+---------+
1 row in results(first row: 0.379s; total: 0.381s)
[host][bigsql] 1> SELECT SUM(GROSS_PROFIT) FROM GOSALESDW.SLS_SALES_FACT_COMPACTED_ORC;
WARN [State: 01003][Code: 0]: Statement processing was successful.. SQLCODE=0, SQLSTATE=01003, DRIVER=3.72.24
+------------------+
| 1 |
+------------------+
| 4615167406.55999 |
+------------------+
1 row in results(total: 3.673 s)
[bigsql@host root]$ hdfs dfs -ls /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_compacted_orc
Found 3 items
drwxrwxrwx - bigsql hadoop 0 2017-12-14 18:14 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_compacted_orc/._biginsights_stats
-rwxrwxrwx 3 bigsql hadoop 19602272 2017-12-15 12:19 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_compacted_orc/000000_0
-rwxrwxrwx 3 bigsql hadoop 3720403 2017-12-15 12:19 /apps/hive/warehouse/gosalesdw.db/sls_sales_fact_compacted_orc/000001_0
注意:這些測試使用單個數據集來測量壓縮表的效能,我們建議您在執行檔案壓縮之前測試自己的基準,並研究該操作帶來的效能優勢。
需要注意的
建議對上述儲存格式的檔案離線執行修改操作,真正的問題是寫入或刪除檔案的操作如何不影響當前正在執行並訪問舊檔案的查詢任務,壓縮檔案本身並不複雜,但是不影響正在使用檔案的任務可能會成為問題。
此外,表資訊儲存在Big SQL
以及Hive Metastore
中,該資訊包含與表關聯的實際檔案的詳細資訊。使用Parquet
工具壓縮檔案時,至少需要更新Hive Metastore
以反映新檔案。Big SQL
具有在Hive Metastore
中拉取更改並將其傳播到其自己的catalog
中的邏輯。