從 Hive 剛推出到現在,得益於社區對它的不斷貢獻,使得 Hive執行 query 效率顯著提升。其中比較有代表性的功能如 Tez (將多個 job整合為一個DAG job)以及 CBO(Cost-based-optimization)。
Hive 在 2.0 版本以后推出了一個新特性名為 LLAP(Live Long And Process),它可以顯著提高 hive query的效率。
LLAP提供了一種混合模型,它包含一個長駐進程,用於直接與DataNode 進行IO交互,並緊密地集成在基於DAG的框架中。Caching,pre-fetching,部分query的執行,以及 access control被移動到此進程執行。
大部分Small/short queries被此進程直接處理。而如果是大型任務(如在reduce階段中的大型shuffle) 則仍被標准的yarn containers 處理。此外,LLAP 還提供了更精細的訪問控制。
類似於 DataNode 進程,LLAP 進程也可被其他應用訪問,特別是在以文件為中心(file-centric)的關系型數據處理(如 join,多表查詢)中。下圖展示了 帶有LLAP 的執行引擎的一個例子:
可以看到,Tez AM 仍作為 Application Master,處理整個任務調度。Query在初始階段即被送往 LLAP。在Reduce階段中,大型的 shuffles 操作在不同的 containers 中執行。多個 queries 與 applications 可以並行地訪問 LLAP。
為了滿足 caching 以及 JIT 優化,以及減少大部分的啟動消耗(startup costs),LLAP 會在每個從節點上啟動一個常駐進程。這個進程用於處理 I/O,caching,以及query中部分片段的執行。
LLAP 與集群中執行引擎共同工作,以保留 Hive 原有的性能(如可擴展性能)。LLAP 並不會替代已存在的執行引擎,而是增強它的功能。這里需要注意的幾點是:
1. 這些進程是可選的。沒有他們,Hive也可以正常工作
2. LLAP 並不是一個執行引擎(如MR or Tez)。一個query 的整個執行過程仍由原有的執行引擎調度與監控。LLAP級別的支持暫時僅對 Tez 可用
3. 取決於query,一個LLAP進程可以提供query的部分結果,或是轉交給外部的Hive Task
4. 資源管理仍由 YARN 負責。在YARN container 分配資源后,執行引擎可以決定哪些資源可以被分配給LLAP,或者它可以啟動 Apache Tez processors 在一個獨立的 YARN container中。
搭建 Hive LLAP
下面介紹一下搭建 LLAP 的流程
1. 安裝 Apache Slider
由於Hive LLAP 基於 Apache Slider,所以需要先在主節點上安裝 Apache Slider。
Github地址地址:https://github.com/apache/incubator-retired-slider/tree/branches/branch-0.92
下載后使用 maven 編譯:mvn clean site:site site:stage package -DskipTests
完成后解壓 apache-slider-0.92.0-incubating/slider-assembly/target/slider-0.92.0-incubating-all.tar.gz
文件目錄如下:
編輯 conf/slider-env,加入 JAVA_HOME 以及 HADOOP_CONF_DIR 環境變量:
編輯 conf/slider-client.xml,指定集群 zookeeper 地址:
<property>
<name>hadoop.registry.zk.quorum</name>
<value>xxxxxx:2181</value>
</property>
將 bin/ 目錄加入 PATH 環境變量,執行 slider 命令,驗證是否安裝成功:
2.LLAP 配置
hive-site.xml 中添加以下參數:
<property>
<name>hive.zookeeper.quorum</name>
<value>xxxxx:2181</value>
</property>
<property>
<name>hive.execution.mode</name>
<value>llap</value>
</property>
<property>
<name>hive.llap.execution.mode</name>
<value>all</value>
</property>
<property>
<name>hive.llap.daemon.service.hosts</name>
<value>@llap_demo</value>
</property>
<property>
<name>tez.runtime.io.sort.mb</name>
<value>150</value>
</property>
使用以下命令生成 llap 環境包:
hive --service llap --name llap_demo\
--instances 2\
--cache 512m\
--executors 4\
--iothreads 4\
--size 4096m\
--xmx 2048m\
--loglevel INFO\
--args "-XX:+UseG1GC -XX:+ResizeTLAB -XX:+UseNUMA -XX:-ResizePLAB -XX:MaxGCPauseMillis=200"\
--javaHome $JAVA_HOME
--instances指定多少個從節點
--cache 指定每個節點的cache大小
--executors 指定節點executors 數量
--iothread 指定每個實例的 io 線程數
--size 指定每個節點的container內存大小
--xmx 指定container JVM 堆大小
--log-lever 指定日志等級
在執行過程中,需要用到 hbase 相關 jar 包,若報錯與此相關,則添加相應依賴到 hive lib,如:
sudo cp -r /usr/lib/hbase/* /usr/lib/hive/lib
執行完成后會生成一個命名為 llap-slider-(%Date) 格式的文件夾,如 llap-slider-19Mar2019,運行文件夾內 run.sh,即可啟動 LLAP 常駐進程,如 yarn 界面下:
此時會在從節點上均啟動一個 container,一般會啟動失敗,報錯為缺少依賴jar 包。在從節點上啟動 container 時,相關 jar 依賴位於 llap-slider-19Mar2019 文件下的 llap-slider-19Mar2019.zip 解壓后的 files 下:
若需要添加 jar 包,則需先解壓 llap-19Mar2019.tar.gz,然后將 jar 包加入此文件夾,最后再打包還原成原目錄結構,例如:
cd llap-slider-19Mar2019
unzip llap-19Mar2019.zip -d unzipped
cd unzipped
cd package
cd files
tar -xvzf llap-19Mar2019.tar.gz
rm -rf llap-19Mar2019.tar.gz
tar -cvzf llap-19Mar2019.tar.gz *
// 添加 jar 包
sudo cp /usr/lib/hadoop/*.jar .
...
rm -rf bin conf config.json lib
cd /home/hadoop/llap-slider-19Mar2019
rm -rf llap-19Mar2019.zip
cd unzipped
zip -r llap-19Mar2019.zip *
cp llap-19Mar2019.zip ../
cd ..
rm -rf unzipped/
啟動成功后,可以在 application master 界面理看到:
測試
在 LLAP 成功啟動后,下面對 Hive query 效率進行測試。這里我們使用 hortonworks 提供的 hive-testbench。
Github地址為:https://github.com/hortonworks/hive-testbench
下載並編譯生成環境后,生成 30 G數據:
./tpcds-setup.sh 30
在 hive shell 中,設置 llap 模式為 none:
hive> set hive.llap.execution.mode=node;
執行提供的示例 sql 語句:
可以看到此任務跑了 131 秒。開啟 llap 模式,再次運行:
hive> set hive.llap.execution.mode=all;
可以看到執行僅耗費 50 秒,前文提到 LLAP 會使用cache優化query,所以若是再次執行同一query,會比之前運行更快:
LLAP 可以顯著提升 Hive query 執行效率。但由於 LLAP 為常駐進程,會持續占用 yarn 可用資源。若集群並不單獨作為 hive 數倉,而是用於各類應用(Spark、Hive 等),則是否在集群使用仍需權衡。