1.想了解HiveServer2的啟動過程,則需要找到啟動HiveServer2的入口,hive服務的啟動命令為hive --service HiveServer2,通過分析$HIVE_HOME/bin下hive指令碼可知,執行hive --service HiveServer2後正真呼叫的是$HIVE_HOME/bin/ext下的hiveserver2.sh指令碼,而從hiveserver2.sh指令碼可以看出,hive服務的入口為HiveServer2類,因此我們需要通過分析HiveServer2類來了解hive的啟動過程。
2.入口方法
在HiveServer2類的入口方法為main方法,該方法中做了以下幾件事:
1)設定載入hive配置的標識的值為true
2)構造ServerOptionsProcessor物件,並呼叫該物件的parse()方法解析引數
3)呼叫LogUtils.initHiveLog4j()方法初始化hive日誌
4)基於命令解析結果獲取執行器,並呼叫execute()方法啟動HiveServer2服務
注:在執行以上四個步驟時,一旦捕獲到異常就會執行System.exit(-1)退出程式。
瞭解了main()的大致邏輯,接下來分析每個步驟的具體實現。
1.ServerOptionsProcessor的parse()方法
在parse()方法中先會通過new GnuParser().parse()方法將引數解析為CommandLine物件,然後呼叫CommandLine的getOptionProperties()獲取hive的配置,並將這些配置設定到系統屬性中,最後根據引數選項選取對應的處理器,並返回對應的引數處理的response結果,主要包括5種情況:
1)當引數選項為H時,處理器為HelpOptionExecutor,即通過列印用法來執行--help選項;
2)當引數選項為deregister時,處理器為DeregisterOptionExecutor,即通過從特定版本的ZooKeeper中登出所有HiveServer2例項來執行--deregister選項;
3)當引數選項為listHAPeers時,處理器為ListHAPeersExecutor,
4)當引數選項為listHAPeers時,處理器為FailoverHS2InstanceExecutor
接下來直接檢視StartOptionExecutor類的execute方法,如下所示:
該方法的核心是1305行startHiveServer2()方法,進入該方法,可以看到該方法裡的所有邏輯都包含在一個while(true)中,這樣做的目的是在HiveServer2失敗後增加重試操作,那什麼會結束該while迴圈呢?有兩種情況,一種是在限制的次數內執行啟動成功,一種是重試次數用完還未執行成功,重試次數為預設值為30秒,重試間隔時間為60秒,可通過配置進行修改,然後來看主要啟動邏輯。
1)啟動hive之前先清除hive快取目錄(/tmp/hive)
根據hive.start.cleanup.scratchdir的值判斷是否需要清理,預設值為false。如果為true,則會根據hive.exec.scratchdir配置的臨時目錄的值,呼叫hdfs介面來刪除該路徑,如下圖所示:
1)建立HiveServer2()例項
建立HIveServer2例項時會將loadHiveServer2Config的值設定為true,該值是標識是否載入hive配置。
2)初始化hive配置
a首先會初始化hive指標;
b建立CLIService例項
c建立ThriftHttpCLIService例項
d獲取當前執行緒的配置單元物件。 如果未初始化,則建立一個新的。如果新配置在後設資料配置中不同,或者所有者不同,則建立一個新的。
e如果配置HA模式,需要在zk上註冊名稱空間
3)呼叫HiveServer2的start()方法啟動hive服務
a呼叫父類(CompositeService)的start()方法,包括啟動CLIService和ThriftHttpCLIService服務
a如果我們支援動態服務發現,則將此HiveServer2例項的服務uri作為znode新增到Zookeeper
b啟動策略同步器
c啟動webServer
d如果未啟用HA,則啟動tez session