將 Azure HDInsight 中的 Apache Hive 查詢最佳化
本文說明一些最常見的效能優化,可用來改善Apache Hive查詢的效能。
叢集類型選取
在 Azure HDInsight 中,您可以在幾個不同的叢集類型上執行 Apache Hive 查詢。
選擇適當的叢集類型,以協助優化工作負載需求的效能:
- 選擇 [互動式查詢 ] 叢集類型,以針對
ad hoc
互動式查詢進行優化。 - 選擇 Apache Hadoop 叢集類型,以針對作為批處理使用的 Hive 查詢進行優化。
- Spark 和 HBase 叢集類型也可以執行 Hive 查詢,而且如果您執行這些工作負載,可能適用。
如需在各種 HDInsight 叢集類型上執行 Hive 查詢的詳細資訊,請參閱 什麼是 Azure HDInsight 上的 Apache Hive 和 HiveQL?。
向外延展背景工作節點
增加 HDInsight 叢集中的背景工作節點數目,可讓工作使用更多對應器和歸納器平行執行。 在 HDInsight 中,有兩種方式可以增加相應放大:
當您建立叢集時,您可以使用 Azure 入口網站、Azure PowerShell 或命令行介面來指定背景工作節點的數目。 如需詳細資訊,請參閱 建立 HDInsight 叢集。 下列螢幕快照顯示 Azure 入口網站 上的背景工作節點設定:
建立之後,您也可以編輯背景工作節點數目,以進一步相應放大叢集,而不需要重新建立一個:
如需調整 HDInsight 的詳細資訊,請參閱 調整 HDInsight 叢集
使用 Apache Tez 而非 Map Reduce
Apache Tez 是 MapReduce 引擎的替代執行引擎。 以 Linux 為基礎的 HDInsight 叢集預設啟用 Tez。
Tez 的速度較快,因為:
- 在 MapReduce 引擎中,以單一作業的形式執行有向非循環圖 (DAG)。 DAG 要求每組對應器後面接著一組 Reducer。 這項需求會導致每個 Hive 查詢有多個 MapReduce 作業遭到關閉。 Tez 沒有這類條件約束,而且可以將複雜的 DAG 處理為一項作業,以將作業啟動額外負荷降至最低。
- 避免不必要的寫入。 多項作業可用來處理 MapReduce 引擎中的相同 Hive 查詢。 每個 MapReduce 作業的輸出都會寫入 HDFS 以取得中繼資料。 由於 Tez 將每個 Hive 查詢的作業數目降到最低,因此可以避免不必要的寫入。
- 將啟動延遲降至最低。 Tez 藉由減少需要啟動的對應器數目,以及改善整個最佳化,以將啟動延遲降到最低。
- 重複使用容器。 只要有可能,Tez 就會重複使用容器,以確保減少啟動容器的延遲。
- 持續最佳化技術。 傳統上會在編譯階段完成最佳化。 不過,我們提供了有關輸入的詳細資訊,可在執行階段進行更好的最佳化。 Tez 會使用持續最佳化技術,讓其進一步將方案最佳化至執行階段。
如需這些概念的詳細資訊,請參閱 Apache TEZ。
您可以使用下列 set 命令在查詢前面加上前置詞,以啟用任何 Hive 查詢 Tez:
set hive.execution.engine=tez;
Hive 數據分割
I/O 作業是執行Hive查詢的主要效能瓶頸。 如果可以減少需要讀取的數據量,則可以改善效能。 根據預設,Hive 查詢會掃描整個Hive數據表。 不過,對於只需要掃描少量數據的查詢(例如,具有篩選的查詢),此行為會產生不必要的額外負荷。 Hive 分割可讓Hive查詢只存取Hive資料表中所需的數據量。
Hive 資料分割是藉由將原始數據重新組織成新的目錄來實作。 每個分割區都有自己的檔案目錄。 使用者定義數據分割。 下圖說明依 [Year] 數據行分割 Hive 數據表。 每年都會建立新的目錄。
一些數據分割考慮:
- 請勿在數據分割 之下 - 在只有少數值的數據行上進行數據分割可能會導致少數數據分割。 例如,在性別上進行分割只會建立兩個分割區(男性和女性),因此將延遲減少最多一半。
- 不要超過數據分割 - 在其他極端情況下,在具有唯一值的數據行上建立數據分割(例如 userid)會導致多個分割區。 在數據分割上,叢集 namenode 會造成很大的壓力,因為它必須處理大量的目錄。
- 避免數據扭曲 - 明智地選擇數據分割索引鍵,讓所有分割區都是偶數大小。 例如,在 [狀態] 數據行上進行數據分割可能會扭曲數據的分佈。 由於加州有近 30 倍的佛蒙特州人口,因此分割區大小可能會扭曲,而且效能可能會有很大的差異。
若要建立數據分割數據表,請使用 Partitioned By 子句:
CREATE TABLE lineitem_part
(L_ORDERKEY INT, L_PARTKEY INT, L_SUPPKEY INT,L_LINENUMBER INT,
L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT STRING)
PARTITIONED BY(L_SHIPDATE STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;
建立資料分割數據表之後,您可以建立靜態數據分割或動態數據分割。
靜態數據分割 表示您已經在適當的目錄中分區化數據。 使用靜態分割區時,您會根據目錄位置手動新增Hive分割區。 下列代碼段是範例。
INSERT OVERWRITE TABLE lineitem_part PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM') SELECT * FROM lineitem WHERE lineitem.L_SHIPDATE = '5/23/1996 12:00:00 AM' ALTER TABLE lineitem_part ADD PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM') LOCATION 'wasb://sampledata@ignitedemo.blob.core.windows.net/partitions/5_23_1996/'
動態數據分割 表示您希望Hive自動為您建立資料分割。 由於您已經從臨時表建立資料分割數據表,您只需要將數據插入數據分割數據表:
SET hive.exec.dynamic.partition = true; SET hive.exec.dynamic.partition.mode = nonstrict; INSERT INTO TABLE lineitem_part PARTITION (L_SHIPDATE) SELECT L_ORDERKEY as L_ORDERKEY, L_PARTKEY as L_PARTKEY, L_SUPPKEY as L_SUPPKEY, L_LINENUMBER as L_LINENUMBER, L_QUANTITY as L_QUANTITY, L_EXTENDEDPRICE as L_EXTENDEDPRICE, L_DISCOUNT as L_DISCOUNT, L_TAX as L_TAX, L_RETURNFLAG as L_RETURNFLAG, L_LINESTATUS as L_LINESTATUS, L_SHIPDATE as L_SHIPDATE_PS, L_COMMITDATE as L_COMMITDATE, L_RECEIPTDATE as L_RECEIPTDATE, L_SHIPINSTRUCT as L_SHIPINSTRUCT, L_SHIPMODE as L_SHIPMODE, L_COMMENT as L_COMMENT, L_SHIPDATE as L_SHIPDATE FROM lineitem;
如需詳細資訊,請參閱 分割數據表。
使用 ORCFile 格式
Hive 支援不同的檔案格式。 例如:
- 文字:預設檔格式,適用於大部分案例。
- Avro:適用於互操作性案例。
- ORC/Parquet:最適合效能。
ORC (Optimized Row Columnar) 格式是儲存 Hive 資料的高效方式。 與其他格式相比,ORC 具有下列優點:
- 支援複雜類型,包括 DateTime 和複雜和半結構化類型。
- 最多 70% 的壓縮。
- 索引每 10,000 個數據列,允許略過數據列。
- 運行時間執行大幅下降。
若要啟用 ORC 格式,您必須先建立包含儲存為 ORC 子句的數據表:
CREATE TABLE lineitem_orc_part
(L_ORDERKEY INT, L_PARTKEY INT,L_SUPPKEY INT, L_LINENUMBER INT,
L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT STRING)
PARTITIONED BY(L_SHIPDATE STRING)
STORED AS ORC;
接下來,您會將數據從臨時表插入 ORC 資料表。 例如:
INSERT INTO TABLE lineitem_orc
SELECT L_ORDERKEY as L_ORDERKEY,
L_PARTKEY as L_PARTKEY ,
L_SUPPKEY as L_SUPPKEY,
L_LINENUMBER as L_LINENUMBER,
L_QUANTITY as L_QUANTITY,
L_EXTENDEDPRICE as L_EXTENDEDPRICE,
L_DISCOUNT as L_DISCOUNT,
L_TAX as L_TAX,
L_RETURNFLAG as L_RETURNFLAG,
L_LINESTATUS as L_LINESTATUS,
L_SHIPDATE as L_SHIPDATE,
L_COMMITDATE as L_COMMITDATE,
L_RECEIPTDATE as L_RECEIPTDATE,
L_SHIPINSTRUCT as L_SHIPINSTRUCT,
L_SHIPMODE as L_SHIPMODE,
L_COMMENT as L_COMMENT
FROM lineitem;
您可以在 Apache Hive 語言手冊中深入瞭解 ORC 格式。
向量化
向量化可讓 Hive 一起處理 1024 個資料列的批次,而不是一次處理一個資料列。 這表示簡單的作業會更快完成,因為需要執行較少的內部程式碼。
若要使用下列設定來啟用Hive查詢的向量化前置詞:
set hive.vectorized.execution.enabled = true;
如需詳細資訊,請參閱 向量化查詢執行。
其他最佳化方法
您可以考慮更多優化方法,例如:
- Hive 貯體: 一種技術,可讓叢集或分割大型數據集,以優化查詢效能。
- 聯結優化: 優化Hive的查詢執行規劃,以改善聯結的效率,並減少使用者提示的需求。 如需詳細資訊,請參閱 聯結優化。
- 增加歸納器。
下一步
在本文中,您已了解數個常見的Hive查詢優化方法。 如需詳細資訊,請參閱下列文章: