如何使用Hadoop提升Hive查詢性能
Apache Hive 是一個 Hadoop 之上構建起來的數據倉庫,用于數據的分析、匯總以及查詢。Hive 提供了一種類 SQL 的接口來查詢被存儲在各種數據源和文件系統中的數據。
使用 Tez Engine
Apache Tez Engine 是一種用來構建高性能批處理與交互式數據處理的可擴展框架。在 Hadoop 中它借助 YARN 實現協作。Tez 通過提高處理速度來對 MapReduce 樣例進行提升,并且保持著 MapReduce 向 PB 量級數據的擴展能了。
你可以通過在環境中將 hive.execution.engine 設置為 tez 來啟用 Tez 引擎:
set hive.execution.engine=tez;
利用矢量化( Vectorization)
矢量化(Vectorization) 通過在一次操作中提取t 1024 行數據提升性能,而不是一次只取一條。它提升了像過濾, 聯合, 聚合等等操作的性能。
Vectorization 可以通過在環境中執行如下命令而得到啟用。
set hive.vectorized.execution.enabled=true;
set hive.vectorized.execution.reduce.enabled=true;
使用 ORCFile
優化的行列格式(Optimized Row Columnar)提供了通過借助比較原來節省 75% 數據存儲的格式來存儲hive數據的高效方法。當要對數據進行讀、寫以及處理操作時,ORCFile 格式較 Hive 文件格式更優。它使用了像謂詞下推、壓縮以及更多其它的技術來提升查詢的性能。
考慮有這樣兩個表: 雇員(employee)以及雇員詳情(employee_details), 這兩個表被存儲在一個文件文件中。假如說我們要使用聯合來從兩個表取出詳情數據。
Select a.EmployeeID, a.EmployeeName, b.Address,b.Designation from Employee a
Join Employee_Details b
On a.EmployeeID=b.EmployeeID;
上面的查詢操作會花掉較長的時間, 因為數據是以文本形式存儲的。將該表轉換成 ORCFile 格式將會顯著減少查詢的執行時間。
Create Table Employee_ORC (EmployeeID int, EmployeeName varchar(100),Age int)
STORED AS ORC tblproperties("compress.mode"="SNAPPY");
Select * from Employee Insert into Employee_ORC;
Create Table Employee_Details_ORC (EmployeeID int, Address varchar(100)
,Designation Varchar(100),Salary int)
STORED AS ORC tblproperties("compress.mode"="SNAPPY");
Select * from Employee_Details Insert into Employee_Details_ORC;
Select a.EmployeeID, a.EmployeeName, b.Address,b.Designation from Employee_ORC a
Join Employee_Details_ORC b
On a.EmployeeID=b.EmployeeID;
ORC 支持壓縮 (ZLIB 和 Snappy), 還有解壓縮的存儲。
利用分區
有了分區, 數據就可以被存儲在 HDFS 上的多個文件夾下。查詢時不回去查詢整個數據集,而是查詢分區的數據集。
創建臨時表并將數據導入臨時表
Create Table Employee_Temp(EmloyeeID int, EmployeeName Varchar(100),
Address Varchar(100),State Varchar(100),
City Varchar(100),Zipcode Varchar(100))
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
LOAD DATA INPATH '/home/hadoop/hive' INTO TABLE Employee_Temp;
創建分區表
Create Table Employee_Part(EmloyeeID int, EmployeeName Varchar(100),
Address Varchar(100),State Varchar(100),
Zipcode Varchar(100))
PARTITIONED BY (City Varchar(100))
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
創建動態的Hive分區
SET hive.exec.dynamic.partition = true;
SET hive.exec.dynamic.partition.mode = nonstrict;
從臨時表向分區表導入數據
Insert Overwrite table Employee_Part Partition(City) Select EmployeeID,
EmployeeName,Address,State,City,Zipcode from Emloyee_Temp;
利用桶裝數據
Hive 表被分割成許多分區而被叫做 Hive 分區。Hive 分區可以被進一步細分成卷或者桶,而被稱作是數據卷或者桶裝數據。
Create Table Employee_Part(EmloyeeID int, EmployeeName Varchar(100),
Address Varchar(100),State Varchar(100),
Zipcode Varchar(100))
PARTITIONED BY (City Varchar(100))
Clustered By (EmployeeID) into 20 Buckets
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
基于成本的查詢優化
Hive 在向最終的執行提交之前會對每一個查詢邏輯和物理執行計劃進行優化。不過,這樣的優化并非基于初始版本 Hive 中的查詢操作的成本來進行的。
在 Hive 的后續版本中,查詢已經根據查詢操作的成本(顯示會執行哪種類型的聯合,如何對聯合操作進行排序,并行的程度等等)進行了優化。
為了利用到基于成本的優化,在查詢的開始部分要設置好如下一些參數。
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;
總結
Apache Hive 是一種非常強大的數據分析工具,而它也支持批量和可交互式的數據處理操作。它是數據分析師和數據科學家最常被用到的工具。當你在處理 PB 量級的數據時,知道如何提升查詢操作的性能是非常重要的。
現在你就知道了如何去提升 Hive 查詢操作的性能!