1. 程式人生 > >(譯)優化ORC和Parquet檔案,提升大SQL讀取效能

(譯)優化ORC和Parquet檔案,提升大SQL讀取效能

簡介

眾所周知,多個Hadoop小檔案(定義為明顯小於HDFS塊大小的檔案,預設情況下為64MB)是Hadoop分散式檔案系統(HDFS)中的一個大問題。HDFS旨在儲存大量資料,理想情況下以大檔案的形式儲存。在HDFS中儲存大量小檔案,而不是儲存較少的大檔案,這在管理檔案的目錄樹時給NameNode增加了額外的開銷。此外,MapReduce和其他讀取HDFS檔案的作業也會受到負面影響,因為它將涉及與HDFS的更多通訊以獲取檔案資訊。

小檔案讀取效能問題對於儲存格式更為嚴重,在儲存格式中,元資料被嵌入檔案中以描述所儲存的複雜內容。IBM Db2 Big SQL使用的兩種常見檔案儲存格式是ORC

Parquet,這些檔案格式以列格式儲存資料,以優化讀取和過濾列的子集。ORCParquet格式將有關列和行組的資訊編碼到檔案本身中,因此,在對檔案中的資料進行解壓縮、反序列化和讀取之前,需要處理元資料。由於這種開銷,處理以邏輯方式捆綁在一起的這些格式的多個小型檔案(例如,屬於Big SQL表或分割槽的檔案)會產生大量成本,並降低IBM Db2 Big SQL的讀取效能。

建議解決方案:壓縮

避免在儲存級別使用小檔案的一個好習慣是對邏輯上屬於一起的目錄裡的小檔案進行壓縮。在Big SQL中,屬於同一表的檔案通常儲存在同一目錄中。IBM Db2 Big SQL的“檔案檢查工具”有助於識別HDFS

中有問題的小檔案,並提供檔案壓縮建議。將這些檔案合併為更大的檔案,會最大程度地減少要處理的元資料並更有效地將檔案大小與HDFS塊對齊,有助於提高Big SQL讀取效能。

ORCParquet提供了它們自己的不同工具來進行檔案合併或壓縮:

  • ORC使用HIVE DDL
  • Parquet使用工具執行合併命令

ORC檔案合併

使用Hive DDLHive 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 SQLApache 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管理大量資源和物件的成本。

效能改進

內部測試表明,壓縮ORCParquet小檔案有助於顯著提高Big SQL的讀取效能。

針對ORCParquet格式進行測試的方案包括:

一百萬行表以兩種方式儲存:

  • HDFS中30個大小不一的非最佳小檔案
  • HDFS中的2個壓縮大檔案,是根據檔案格式使用parquet toolsHive 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中的邏輯。

參考資料

編譯自:Optimizing ORC and Parquet files for Big SQL qu