天天看點

Hive源碼分析:CLI入口類啟動腳本入口類總結

說明:

本文的源碼分析基于hive-0.10.0-cdh4.3.0。

從shell腳本<code>/usr/lib/hive/bin/ext/cli.sh</code>可以看到hive cli的入口類為<code>org.apache.hadoop.hive.cli.clidriver</code>

java中的類如果有main方法就能運作,故直接查找<code>org.apache.hadoop.hive.cli.clidriver</code>中的main方法即可。

clidriver類中的方法有:

Hive源碼分析:CLI入口類啟動腳本入口類總結

main方法代碼如下:

閱讀run函數可以看到,主要做了以下幾件事情:

讀取main方法的參數

重置預設的log4j配置并為hive重新初始化log4j,注意,在這裡是讀取hive-log4j.properties來初始化log4j。

建立clisessionstate,并初始化in、out、info、error等stream流。clisessionstate是一次指令行操作的session會話,其繼承了sessionstate。

重指令行參數中讀取參數并設定到clisessionstate中。

啟動sessionstate并連接配接到hive server

如果cli是本地模式運作,則加載<code>hive.aux.jars.path</code>參數配置的jar包到classpath

建立一個clidriver對象,并設定目前選擇的資料庫。可以在指令行參數添加<code>-database database</code>來選擇連接配接那個資料庫,預設為default資料庫。

加載初始化檔案<code>.hiverc</code>,該檔案位于目前使用者主目錄下,讀取該檔案内容後,然後調用processfile方法處理檔案内容。

如果指令行中有-e參數,則運作指定的sql語句;如果有-f參數,則讀取該檔案内容并運作。注意:不能同時指定這兩個參數。

如果沒有指定上面兩個參數,則從目前使用者主目錄讀取<code>.hivehistory</code>檔案,如果不存在則建立。該檔案儲存了目前使用者所有運作的hive指令。

在while循環裡不斷讀取控制台的輸入内容,每次讀取一行,如果行末有分号,則調用clidriver的processline方法運作讀取到的内容。

每次調用processline方法時,都會建立signalhandler用于捕捉使用者的輸入,當使用者輸入ctrl+c時,會kill目前正在運作的任務以及kill掉目前程序。kill目前正在運作的job的代碼如下.

處理hive指令。

如果輸入的是quit或者exit,則程式退出。

如果指令開頭是source,則會讀取source 後面檔案内容,然後執行該檔案内容。通過這種方式,你可以在hive指令行模式運作一個檔案中的hive指令。

如果指令開頭是感歎号,執行作業系統指令(如<code>!ls</code>,列出目前目錄的檔案資訊)。通過以下代碼來運作:

shell_cmd的内容大概如下:

如果指令開頭是list,列出jar/file/archive

如果是遠端模式運作指令行,則通過hiveclient來運作指令;否則,調用processlocalcmd方法運作本地指令。

以本地模式運作時,會通過commandprocessorfactory工廠解析輸入的語句來獲得一個commandprocessor,commandprocessor接口的實作類見下圖:

Hive源碼分析:CLI入口類啟動腳本入口類總結

從上圖可以看到指定的指令(<code>set/dfs/add/delete/reset</code>)交給指定的commandprocessor處理,其餘的(指hql語句)交給driver類來處理。

故,<code>org.apache.hadoop.hive.ql.driver</code>類是hql查詢的起點,而run()方法會先後調用compile()和execute()兩個函數來完成查詢,是以一個command的查詢分為compile和execute兩個階段。

作為嘗試,第一次使用思維導圖分析代碼邏輯,簡單整理了一下clidriver類的運作邏輯,如下圖。以後還需要加強畫圖和表達能力。

Hive源碼分析:CLI入口類啟動腳本入口類總結