天天看點

HiveServer2表結構變更太耗時分析

轉至中繼資料結尾

  • 建立: 李星,最新修改于: 十二月 23, 2016

轉至中繼資料起始

HiveServer2啟動端口為10002,可以看到大量galaxy過來的請求以及少量主資料過來的請求。

HiveServer2表結構變更太耗時分析

jstack檢視HiveServer2的程序,發現有大量線程被block了。

HiveServer2表結構變更太耗時分析

發現大都是block在了org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1122) 這上,hive 1.2.1相應源碼如下圖所示。

HiveServer2表結構變更太耗時分析

可以看到Driver類的compileInternal函數中有個synchronized,并且compileMonitor變量是static的。

HiveServer2表結構變更太耗時分析

由于HiveServer2就是一個Java程序,即使多個請求過來,開啟了多線程進行處理,每個線程都有一個Driver類,但這個static鎖會把所有線程的Driver都鎖住。也就是說,HiveServer2中使用Driver類進行compile的過程是串行的。這解釋了為什麼會有那麼多個線程block在compileInternal函數上,再次使用jstack檢視各線程狀态,發現确實是有一個線程進入了同步塊,其他的則在等待。

HiveServer2表結構變更太耗時分析

從上面的hive架構圖可以看到,compiler需要從metastore擷取中繼資料資訊。經過遠端調試(hive --debug)發現普通表結構變更語句的compile是非常快就完成的,但如果變更語句帶了cascade後在compile時會有2個地方耗時特别長。在我的測試用例中,sem.analyze(tree, ctx);這句大概會卡5分鐘,doAuthorization(sem, command);這句會卡10分鐘左右。從源碼來看,具體耗時會和分區數量有很大關系,doAuthorization中會檢查每個分區的權限。

HiveServer2表結構變更太耗時分析
HiveServer2表結構變更太耗時分析

是以,一旦執行時遇到了某個表結構變更語句帶了cascade參數,由于compile時需要較長時間,進而導緻其他變更語句都需要等待其compile完成才能進行compile。

另外由于HiveServer2會每5分鐘通過BeeLine進行檢測,也加劇了HiveServer2的負擔,同時每2小時會kill HiveServer2重新開機,是以等待超過2個小時的也不可能會有結果。是以,使用者說建立表時也卡了非常久、變更表結構幾個小時也沒傳回都可以解釋得通。

總結:

HiveServer2的compile是串行的,而加上cascade關鍵字時會導緻compile時間需要十幾甚至幾十分鐘,compile過程成為一個非常大的瓶頸。包含了cascade的多個表結構變更語句在一段時間内一起送出時就會在compile階段進行排隊等待了。

另外,帶有cascade的DDL在執行階段肯定也會比普通的DDL更耗時,但沒進行測試,不過執行DDL應該是可以并行的。

後續:

搜尋了下發現社群似乎在Hive 2.0.0版本上新增了相關的參數用于設定是否開啟并行compile。

Remove lock on compilation stage:https://issues.apache.org/jira/browse/HIVE-4239

HiveServer2表結構變更太耗時分析

patch在compileInternal函數上的主要修改就是增加了判斷語句,如果是HiveServerQuery并且開啟了并行compile,則不會進行加鎖(patch中加鎖方式從用synchronized關鍵字改成了ReentrantLock類)。

HiveServer2表結構變更太耗時分析

繼續閱讀