問題分析報告--Hive表列屬性更新慢並偶爾更新失敗

問題分析報告--Hive表列屬性更新慢並偶爾更新失敗


1、問題描述

1.1 基本信息[Basic Information]

  • 集羣規模:37+3臺物理機,每臺128G內存;CPU:2*16C;SATA磁盤,2T*12
  • hadoop社區版本:**
  • 商業版本:FusionInsight_HD_V100R002C30LCN001SPC005
  • MetaStore:高斯數據庫(Postgresql)

1.2 問題描述[Problem Description]

  • 10月16日,在執行批量任務時,alter table test change column id id int comment ‘my comment’這類語句執行比較慢,該表150多個分區, 執行需要200多s;
  • 在10月13日,同樣的操作,只需要10多s。
  • 在執行批量任務時,alter table test change column id id int comment ‘my comment’這類語句偶現失敗。

2、問題分析[Problem Analysis]

2.1 Hive表列屬性偶現失敗問題分析

直接在現網重現該問題,並獲取日誌後進行分析:

1.HiveServer在01:45:31接收到Alter table列信息的請求:

2016-10-16 01:45:31,335 | INFO  | HiveServer2-Background-Pool: Thread-45308 | Starting command: alter table hw_test2 change column log_id            log_id            decimal(24,9)  comment '日誌號5' | org.apache.hadoop.hive.ql.Driver.execute(Driver.java:1257)

2.HiveServer向10.0.11.11節點的metaStore發起客戶端連接:

2016-10-16 01:45:31,336 | INFO  | HiveServer2-Background-Pool: Thread-45308 | Trying to connect to metastore with URI thrift://10.0.11.11:21088 | org.apache.hadoop.hive.metastore.HiveMetaStoreClient.open(HiveMetaStoreClient.java:378)

3.MetaStore審計日誌記錄了本次alter table的請求:

2016-10-16 01:45:31,355 | INFO  | pool-6-thread-187 | UserName=hdmp     UserIP=10.0.11.11       Time=2016/10/16 01:45:31     Opertaion=alter_table: db=tmp tbl=hw_test2 newtbl=hw_test2

4.由於執行表的alter table操作的同時,會遍歷修改該表下的所有分區的列的元數據信息,因此在分區數比較多的情況下會耗時較長。而當時HiveServer與MetaStore之間的連接超時時間設置成了10分鐘,如果10分鐘還沒有完成一次任務執行,HiveServer會認爲其MetaStore連接超時,並拋出異常,然後進行重連

2016-10-16 01:55:31,453 | WARN  | HiveServer2-Background-Pool: Thread-45308 | MetaStoreClient lost connection. Attempting to reconnect. | org.apache.hadoop.hive.metastore.RetryingMetaStoreClient.invoke(RetryingMetaStoreClient.java:133)

org.apache.thrift.transport.TTransportException: java.net.SocketTimeoutException: Read timed out

       at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:129)

       at org.apache.thrift.transport.TTransport.readAll(TTransport.java:84)

5.於是HiveServer向另一個MetaStore 11.12發起了連接:

2016-10-16 01:55:32,481 | INFO  | HiveServer2-Background-Pool: Thread-45308 | Trying to connect to metastore with URI thrift://10.0.11.12:21088 | org.apache.hadoop.hive.metastore.HiveMetaStoreClient.open(HiveMetaStoreClient.java:378)

6.連接到11.12後重試alter table的請求:

2016-10-16 01:55:32,527 | INFO  | pool-6-thread-2 | UserName=hdmp  UserIP=10.0.11.11       Time=2016/10/16 01:55:32     Opertaion=alter_table: db=tmp tbl=hw_test2 newtbl=hw_test2       | org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.logAuditEvent(HiveMetaStore.java:365)

7.第一次連接中,由於請求已經發送到MetaStore服務端,當客戶端超時認爲失敗後斷開,MetaStore服務端對於元數據庫的修改動作仍在繼續運行直到2點08分這個alter table請求執行成功:

2016-10-16 02:08:59,065 | INFO  | pool-6-thread-187 | UserName=hdmp     UserIP=10.0.11.11       Time=2016/10/16 02:08:59     Opertaion=alter_table    result=success details=null      | org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.logAuditEvent(HiveMetaStore.java:365)

8.從01:45到02:08之間,第一次發起的請求一直在更新元數據表的信息,MetaStore服務端持有了表的元數據的行鎖,而01:55時,第二次發起了同樣的請求,則需要等待第一次請求持有的鎖釋放。然而第一次的任務一直持續到02:08,因此,第二次請求到達10分鐘超時時間02:05時,仍未獲取到鎖,任務本次請求失敗,向客戶端拋出失敗異常。

2016-10-16 02:05:38,979 | ERROR | pool-6-thread-2 | Database access problem. Killing off this connection and all remaining connections in the connection pool. SQL State = 08006 | com.jolbox.bonecp.ConnectionHandle.markPossiblyBroken(ConnectionHandle.java:388)

2016-10-16 02:05:38,980 | ERROR | pool-6-thread-2 | Update of object "org.apache.hadoop.hive.metastore.model.MStorageDescriptor@24b03fe" using statement "UPDATE SDS SET CD_ID=? WHERE SD_ID=?" failed : org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.

       at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:374)

對應失敗的審計日誌:

2016-10-16 02:05:38,983 | INFO  | pool-6-thread-2 | UserName=hdmp  UserIP=10.0.11.11       Time=2016/10/16 02:05:38     Opertaion=alter_table     result=failed     details=MetaException(message:The transaction for alter partition did not commit successfully.)      | org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.logAuditEvent(HiveMetaStore.java:365)

9.進一步分析10分鐘超時的產生原因,從元數據庫獲取到的調試信息中可以看到對應時間的鎖阻塞情況,第二次01:55開始啓動的請求,爲需要更新Hive元數據庫中的SDS表,被第一次的請求鎖住了13分鐘  


10.而第一次請求的執行時間慢的原因在於,測試表的分區數量爲1072個,每個請求都需要更新保存列信息的元數據表COLUMNS_V2,而該表會通過外鍵關聯到核心表SDS,SDS表具有大量的外鍵與其他表進行關聯。 


11.從關聯關係中可以看出,在修改列信息的時候會聯動更新若干元數據表的記錄,其中包括元數據核心的SDS表。而針對來自CDS表的外鍵CD_ID沒有創建索引,在聯動修改過程中,需要全表掃描SDS表。 


12.在當前SDS數據量達到200W以上級別的前提下,一次全表掃描耗時940ms左右,即每個分區的列信息更新操作,達到一秒左右的時間,1000個分區需要花費1000秒以上。

[2016-10-16 17:22:32.367 CST] gaussdb 12750 LOG: duration: 942.519 ms execute <unnamed>: SELECT 'org.apache.hadoop.hive.metastore.model.MStorageDescriptor' AS NUCLEUS_TYPE,A0.INPUT_FORMAT,A0.IS_COMPRESSED,A0.IS_STOREDASSUBDIRECTORIES,A0.LOCATION,A0.NUM_BUCKETS,A0.OUTPUT_FORMAT,A0.SD_ID FROM SDS A0 WHERE A0.CD_ID = $1 LIMIT 1 OFFSET 0 


2.2 Hive表列屬性更新慢問題分析

直接在現網重現該問題,並獲取日誌後進行分析:

1.從執行的SQL語句日誌分析, 在修改列信息的時候會聯動更新若干元數據表的記錄,其中包括元數據核心的SDS表。而針對來自CDS表的外鍵CD_ID沒有創建索引,在聯動修改過程中,需要全表掃描SDS表。 


2.在當前SDS數據量達到200W以上級別的前提下,一次全表掃描耗時940ms左右,即每個分區的列信息更新操作,達到一秒左右的時間,1000個分區需要花費1000秒以上。

[2016-10-16 17:22:32.367 CST] gaussdb 12750 LOG: duration: 942.519 ms execute <unnamed>: SELECT 'org.apache.hadoop.hive.metastore.model.MStorageDescriptor' AS NUCLEUS_TYPE,A0.INPUT_FORMAT,A0.IS_COMPRESSED,A0.IS_STOREDASSUBDIRECTORIES,A0.LOCATION,A0.NUM_BUCKETS,A0.OUTPUT_FORMAT,A0.SD_ID FROM SDS A0 WHERE A0.CD_ID = $1 LIMIT 1 OFFSET 0

3.我們模擬了數據量在有無索引情況下的性能:

 

同樣的表,同樣的數據量,在加索引前,是800多ms,跟生產環境一樣, 加了索引之後,就變成0.1ms,性能提升了幾百倍,因此, 性能慢的問題,判斷爲缺少索引導致的。

4.Alter table add comment有3三種不同表現,a是以前沒有comment的,新增comment;b是已經有comment,修改成不同comment,c是已經有comment,修改成相同comment;這三種情況,b因爲要插入sds,查詢sds,因此耗時最長,c因爲hive使用的datanucleaus組件能判斷出沒有發生變化,沒有操作sds表,因此耗時最短

5.針對用戶反饋10.13號只需要10多秒, 而近期增加的分區信息並沒有那麼多, 爲什麼性能下降這麼快的問題, 將生產環境的dbservice備份數據導入測試環境中, 發現相同的表,執行alter操作需要300s左右,而在增加索引後, 變成了7s,性能提升巨大.


3、根本原因[Root Cause]

3.1 Hive表列屬性偶現失敗

    本問題主要包括兩個方面:

  1. HiveServer與MetaStore客戶端連接超時時間未按照集羣規模進行合理配置;
  2. 對於大數據量頻繁讀元數據表的情形,缺少針對性優化。

3.2 Hive表列屬性更新慢

  1. 系統建表未建立索引爲可優化點,根據內部測試,建立索引後性能有較大幅度的提升。
  2. 用戶之前反應比較快,根據生產環境到測試環境的重建,發現執行修改comment,需要相似的時間,用戶反應之前快,可能是上邊分析中修改的comment前後一樣導致的.


4、解決措施[Corrective Action]

4.1 Hive表列屬性偶現失敗

  • 臨時解決措施[Workaround]:將HiveServer與MetaStore連接超時時間調長,使之能滿足業務場景需要,恢復業務運行。
  • 最終解決措施[Solution]:爲元數據中需要頻繁訪問的表添加索引,提升訪問效率。

4.2 Hive表列屬性更新慢

  • 優化措施[Workaround]:針對查詢慢的問題, 建議在系統空閒時對錶增加索引,提升查詢性能


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