#下載編譯 在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
是沒有勾選的,這裏勾選上它,它所指定的相應依賴就會被導入,源碼就不會標紅啦!就可以放心的改源碼啦!
如下圖:
#開啓調試之旅 ##調試前提 調試代碼時最好不執行完全分佈式任務(會分配到多臺節點機執行的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_socket | JPDA front-end和back-end之間的傳輸方法,dt_socket表示使用套接字傳輸 |
server=y | y表示啓動的JVM是被調試者,如果爲n,則表示啓動的JVM是調試器 |
suspend=n | y表示啓動的JVM會暫停等待,直到調試器連接上才繼續執行,而suspend=n,則JVM不會暫停等待 |
address=5005 | JVM在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
即可進入監聽狀態,IDEA進行遠程連接即可
歡迎閱讀轉載,轉載請註明出處:https://my.oschina.net/u/2539801/blog/867314