0817-6.3.3-Impala執行DDL慢問題分析報告

作者:餘楓

問題描述



隨着集羣使用時間的增長,在Impala中執行DDL語句消耗的時間越來越長,排查該問題時進行測試,create一張表的耗時達到4-5s,drop一張表的時間5-10s,該問題影響了Impala的日常跑批工作。


問題分析過程



初次排查該問題時,通過創建一個測試表的方式,在日誌中跟蹤該表創建的整個流程,當SQL提交到Impala Daemon後,由於是DDL語句,會由Catalog接收到請求後去找Hive Metastore Server獲取元數據,在查看Catalog日誌時發現,整個create語句花了大概5s的時間,如下日誌所示:

I0826 13:16:09.467458 27720 Frontend.java:1286a94da42385ea3b67:75e09b7100000000Analysis finished.
I0826 13:16:14.363976 27720 ImpaladCatalog.java:200a94da42385ea3b67:75e09b7100000000AddingTABLE:default.testing version: 8227 size: 51


在查看Hive Metastore Server日誌時發現,Hive Metastore Server很快就響應了Catalog的請求,但是卻沒有顯示什麼時間返回了操作結果,如下日誌所示:

2020-08-26 13:16:09,515 INFO org.apache.hadoop.hive.metastore.HiveMetaStore: [pool-9-thread-160]: 171: create_table: Table(tableName:testing, dbName:default, owner:bdp_usr, ...
2020-08-26 13:16:09,840 INFO org.apache.hadoop.hive.common.FileUtils: [pool-9-thread-160]: Creating directory if it doesn't exist: hdfs://UATHA/user/hive/warehouse/testing


在Catalog獲取到Hive Metastore Server返回的元數據後,會馬上返回給Impala Daemon,通過Statestore同步元數據到所有的Impala Daemon,在下面的日誌中可以看到廣播元數據的操作和Catalog中執行完DDL語句的時間相差並不長,證明Statestore廣播元數據的環節也並無問題,日誌如下:

I0826 13:16:15.569249 27198 catalog-server.cc:611] Collected update1:TABLE:default.testing, version=8227, original size=51, compressed size=50


通過上面日誌的分析結果,初步判斷,執行DDL慢的主要時間是消耗在Hive Metastore Server內部,後續通過修改了Hive Metastore Server的日誌級別來進一步確定耗時發生的具體環節。


在查看DEBUG級別的Hive Metastore Server日誌時發現,問題主要出在Sentry上,Hive Metastore Server在創建/刪除一個表或者數據庫的時候都需要通知Sentry同步元數據。從下面的日誌中可以看到Hive Metastore Server發出這個通知(Notifying sentry about Notification for CREATE_TABLE (id: 133299))之後等了將近6秒才收到返回消息,這就是爲什麼DDL慢的原因。日誌如下所示:

2020-08-27 13:11:54,991 DEBUG org.apache.hadoop.hive.ql.log.PerfLogger: [pool-9-thread-59]: <PERFLOG method=create_table_with_environment_context from=org.apache.hadoop.hive.metastore.RetryingHMSHandler>
...
2020-08-27 13:11:55,532 DEBUG org.apache.sentry.binding.metastore.SentrySyncHMSNotificationsPostEventListener: [pool-9-thread-59]: Notifying sentry about Notification for CREATE_TABLE (id: 133299)
2020-08-27 13:11:55,532 DEBUG org.apache.sentry.core.common.transport.SentryTransportPool: [pool-9-thread-59]: [1] obtained transport nyuatdn01:8038
2020-08-27 13:11:55,533 DEBUG org.apache.sentry.core.common.transport.SentryTransportPool: [pool-9-thread-59]: Currently 1 active connections, 9 idle connections
2020-08-27 13:11:55,533 DEBUG org.apache.sentry.core.common.transport.RetryClientInvocationHandler: [pool-9-thread-59]: Calling notifyHmsEvent
2020-08-27 13:11:55,533 DEBUG org.apache.thrift.transport.TSaslTransport: [pool-9-thread-59]: data length before wrap: 177
2020-08-27 13:11:55,533 DEBUG org.apache.thrift.transport.TSaslTransport: [pool-9-thread-59]: writing data length: 237

<----- 在此等待了將近6

2020-08-27 13:12:01,132 DEBUG org.apache.thrift.transport.TSaslTransport: [pool-9-thread-59]: CLIENT: reading data length: 129
2020-08-27 13:12:01,136 DEBUG org.apache.thrift.transport.TSaslTransport: [pool-9-thread-59]: data length after unwrap: 69
2020-08-27 13:12:01,136 DEBUG org.apache.sentry.binding.metastore.SentrySyncHMSNotificationsPostEventListener: [pool-9-thread-59]: Finished Notifying sentry about Notification for CREATE_TABLE (id: 133299)
2020-08-27 13:12:01,136 DEBUG org.apache.sentry.binding.metastore.SentrySyncHMSNotificationsPostEventListener: [pool-9-thread-59]: Latest processed event ID returned by the Sentry server: 133299
2020-08-27 13:12:01,136 DEBUG org.apache.sentry.core.common.transport.SentryTransportPool: [pool-9-thread-59]: [1returning nyuatdn01:8038
2020-08-27 13:12:01,137 DEBUG org.apache.hadoop.hive.ql.log.PerfLogger: [pool-9-thread-59]: </PERFLOG method=create_table_with_environment_context start=1598505114991 end=1598505121136 duration=6145 from=org.apache.hadoop.hive.metastore.RetryingHMSHandler threadId=50 retryCount=0 error=false>


定位到Sentry服務的問題後,初步查看Sentry的日誌發現,create table的平均時間爲3.7s,但是同樣的ddl上create database的平均時間只有14ms,日誌如下:

2020-08-27 13:12:29,580 INFO org.apache.sentry.api.service.thrift.SentryMetrics: type=TIMER, name=org.apache.sentry.provider.db.service.persistent.HMSFollower.create_database, count=587min=7.288829max=82.173701, mean=14.025413855401405, stddev=0.17108183329537113, median=14.007352, p75=14.007352, p95=14.007352, p98=14.007352, p99=15.618253999999999, pXXX-XX-XXXX53999999999, mean_rate=0.003335984152712016, m1=0.0035923052762600865, m5=0.003874149637852582, m15=0.003536851393822959, rate_unit=events/second, duration_unit=milliseconds
2020-08-27 13:12:29,581 INFO org.apache.sentry.api.service.thrift.SentryMetrics: type=TIMER, name=org.apache.sentry.provider.db.service.persistent.HMSFollower.create_table, count=2436min=8.204786max=5710.664941999999, mean=3755.5881518186834, stddev=2296.0499299404587, median=5163.032873, p75=5163.032873, p95=5163.032873, p98=5163.032873, p99=5163.032873, p999=5163.032873, mean_rate=0.013844166161343525, m1=0.015050441350939393, m5=0.0072619687637006745, m15=0.01947849264485575, rate_unit=events/second, duration_unit=milliseconds


進一步查看Sentry的日誌找到了之前執行測試的建表信息,日誌中的兩條消息的時間間隔正好與Hive Metastore Server裏的耗時吻合。通過Support查看Sentry的代碼確認,第二條消息是Sentry爲新建的表添加owner權限之後馬上打印的。而第一條消息是執行數據庫操作的DataNucleus代碼裏記錄的。這兩條消息說明了時間都花在了數據庫操作上。


上面的日誌看到的Sentry日誌裏的指標值顯示create/drop數據庫並不慢的原因是因爲這些操作是HMS的canary測試操作。這些操作因爲沒有owner所以不需要Sentry給它們賦予owner權限所以不用記錄到數據庫。而從Impala裏發起的create/drop table操作都需要修改owner權限,而這些修改是在數據庫上完成的,所以花費的時間比較長。


以上發現都表明這個問題的根源應該在Sentry的後臺數據庫上,後續將測試環境的Sentry元數據dump出來提供給了Support,Support在拿到Sentry的庫後重現了DDL慢的問題,在測試集羣的Sentry服務裏配置項OWNER Privileges for Sentry Policy Database Objects(sentry.db.policy.store.owner.as.privilege)設置成了“ALL privileges with GRANT”。這意味着每當一個用戶創建一個表的時候sentry都要往數據庫裏爲這個用戶添加這個表的owner權限。反之,刪除一個表的時候sentry也要刪除用戶在這個表上的owner權限。在數據庫dump裏查看到用戶bdp_usr有4000多條owner權限。在把sentry.db.policy.store.owner.as.privilege設置成NONE之後建表不到1秒鐘即可完成。


問題處理結論



修改Sentry服務的配置項sentry.db.policy.store.owner.as.privilege爲NONE,修改方式如下:


修改完成後保存配置按照提示重啓服務即可。


總結



1.Owner權限是Sentry裏的權限。這個功能打開之後,創建數據庫或者表的用戶自動獲得這個對象上的owner權限。但是在HDFS上對應的目錄還是屬於hive用戶。


2.Owner權限只存在於Sentry數據庫中並被Sentry客戶端在調用Sentry API的時候使用。與HDFS等都無關。在沒有開啓這個功能的情況下Sentry不會在創建數據庫或者表的時候添加owner權限。也就是說對於新建的表或者數據庫的owner都是空。Sentry通過判斷其他權限比如CREATE/ALL/SELECT等判斷用戶是否可以對某個對象執行特定的操作。而在開啓了這個功能之後,用戶在建表或者數據庫的時候自動獲得owner權限,不需要額外授權就可以訪問他自己創建的對象。

本文分享自微信公衆號 - Hadoop實操(gh_c4c535955d0f)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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