Hive源碼編譯及閱讀修改調試 原 薦

#下載編譯 在git上下載合適的master分支,使用maven編譯。執行編譯的目的在於,確保過程中生成的代碼(Thrift)已經生成,這樣導入IDEA就不會出現有些類找不到的情況。

執行源碼編譯分發命令,進入源碼根目錄執行:

mvn clean package -Phadoop-2 -DskipTests -Pdist

這裏必須指定profile爲hadoop-2來支持hadoop 2.x版本

1、後續更改完源碼後,還需執行該命令來編譯打包。源碼更改後需評價其對Hive各模塊的影響(改動代碼多的話可通過pom的依賴來看),如果影響的模塊非常少,可以直接進入相應的模塊進行上述命令的編譯打包,如果影響模塊很多,則直接在Hive源碼根目錄進行編譯打包。

2、打完包後,將受影響的包進行線上替換,重啓受影響的組件即可應用上改後的代碼。如果在CDH環境,要注意所有YARN的節點都需進行包的替換,因爲Hive的MR任務啓動後,節點上Container的啓動其核心包是加載的本地jar包,而不是HDFS上的jar包。

#導入IDEA進行源碼閱讀修改 在Intellij裏打開編譯後的工程,它是一個Maven工程,軟件會自動區分模塊並導入。導入後可以看到源碼,但我們會發現,很多關於hadoop的地方標紅了,表示不可用,這是爲什麼呢?

這是因爲版本依賴的原因,hive可編譯爲依賴 hadoop1 或 hadoop2,在編譯源碼的時候就已提示過讓我們輸入支持哪個,否則不能編譯!

這裏也一樣,需要我們選擇其依賴,才能正確的導入maven依賴包!

在Intellij的右側,有個maven project的停靠欄,點擊它可以看到有個 profiles的子項,我們可以明顯看到hadoop-2是沒有勾選的,這裏勾選上它,它所指定的相應依賴就會被導入,源碼就不會標紅啦!就可以放心的改源碼啦!

如下圖:

IDEA Maven

#開啓調試之旅 ##調試前提 調試代碼時最好不執行完全分佈式任務(會分配到多臺節點機執行的MR任務),代碼跑動控制在當前JVM範圍內(可以是多線程的),否則代碼跟蹤超級麻煩。

如果需要執行MR任務,最好以local模式執行,打開命令SET mapreduce.framework.name=local;

有些任務也不需要起MR,這樣更方便調試,儘可能不起MR:set hive.exec.mode.local.auto = true;,並調大hive.exec.mode.local.auto.tasks.max(默認4)hive.exec.mode.local.auto.inputbytes.max(默認128M),當且僅當自動開啓本地模式設爲true,並且輸入的文件數量和數據量大小分別都小於這兩個值的時候,纔不會起MR任務。

1、Hive起完全分佈式的MR任務也可追蹤,但是需要修改節點機上的MR啓動時Java參數,而且Hive起一個MR任務時,只有當MR啓動後才能知道哪個節點機上啓動了該任務,之後才能進行Remote debug連接,這在運行環境爲完全分佈式時會比較麻煩。但如果運行環境爲僞分佈式,那麼追蹤可能會更方便些。

2、Hive調試,實際運行環境爲僞分佈式集羣環境或完全分佈式集羣環境都可以。

Hive調試需保證調試代碼和運行環境的代碼一致,否則調試會出現斷點位置對不上的問題,影響我們調試。

如果是在Kerberos環境,運行Hive命令的用戶需具備Kerberos認證,因爲調試跟正常執行任務其實沒什麼區別。調試端(如Windows上的IDEA)不需要認證,它只要能連通開啓的JVM端口即可。

##調試原理 基於Sun Microsystem 的 Java Platform Debugger Architecture (JPDA) 技術,它由兩個接口(分別是 JVM Tool Interface 和 JDI)、一個協議(Java Debug Wire Protocol)和兩個用於合併它們的軟件組件(後端和前端)組成,可以遠程調試任何基於JVM的程序。

要啓用調試,只需在軟件的JVM啓動時加載以下參數:

-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

參數含義:

參數含義
-Xdebug啓用調試特性
-Xrunjdwp啓用JDWP實現,包含若干子選項: transport, server, suspend, address
-transport=dt_socketJPDA front-end和back-end之間的傳輸方法,dt_socket表示使用套接字傳輸
server=yy表示啓動的JVM是被調試者,如果爲n,則表示啓動的JVM是調試器
suspend=ny表示啓動的JVM會暫停等待,直到調試器連接上才繼續執行,而suspend=n,則JVM不會暫停等待
address=5005JVM在5005端口上監聽請求,這個設定爲一個不衝突的端口即可

##Hive Cli 調試 在運行環境開啓Hive Cli命令行,執行: bin/hive --debug -hiveconf hive.root.logger=DEBUG,console,此時界面會顯示 Listening for transport dt_socket at address: 8000,表明遠程調試模式已開。

然後在IntelliJ裏配置遠程調試模式,Run -> Debug -> Edit Configurations,然後點左上角 + 號按鈕,選擇 Remote,配好Host爲運行Hive Cli命令的主機,Port爲8000,然後起個方便識別的名字,點擊Debug就可以開始調試源碼了。

一旦這邊遠程連接上了集羣環境的調試端口,集羣那邊就會打日誌並出現hive >這樣的輸入光標,在IDEA裏打斷點,然後在Hive Cli裏執行HQL語句,我們就可以看到IDEA這邊的斷點信息,然後逐步調試。

##HiveServer2 調試 以下以CDH集羣環境做說明,路徑與你安裝的CDH路徑有關,Apache開源環境找到對應配置文件即可。

修改hiveserver2所在機器的/opt/cloudera/parcels/CDH/lib/hive/bin/hive-config.sh文件,在最後加上

export HADOOP_OPTS="$HADOOP_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
export HADOOP_VERSION="2.6.0-cdh5.5.1"

其中HADOOP_VERSION由命令hadoop version可得到。

改完配置後在CM裏重啓Hiveserver2,這時在HiveServer2所在機器上查看5005端口,會發現處於監聽狀態,然後利用Intellij如上面的debug一樣,即可連接上遠程的hiveserver2。

打好斷點,之後在某一節點上啓動beeline,連接上該hiveserver2,執行hql,這邊就可以源碼追蹤。

1、注意端口別佔用了,否則會報: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT

2、如果整個Hive需要重啓,需把上面更改註釋掉,待Hive重啓完畢後,再把註釋改回來然後單獨重啓HiveServer2。這是因爲Hive MetaStore啓動時也會用到該腳本,而MetaStore先啓動,會進入MetaStore的調試。之後啓動HiveServer2時就會出現端口占用的情況

##Beeline 調試 以下以CDH集羣環境做說明,自己的安裝環境尋找相應配置即可

修改需要運行beeline的機器上的beeline腳本的執行腳本,我的位置爲:/opt/cloudera/parcels/CDH/lib/hive/bin/ext/beeline.sh,在腳本最後的export HADOOP_CLIENT_OPTS後加上 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

如下:

beeline

改完後,在該機器上執行beeline即可進入監聽狀態,IDEA進行遠程連接即可

歡迎閱讀轉載,轉載請註明出處:https://my.oschina.net/u/2539801/blog/867314

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章