HiveMetaStore状态不良导DDLSQL耗时200s以上
HMS进程报错:hive metastore server Failed to sync requested HMS notifications up to the event ID xxx
原因分析:查看sentry异常CounterWait源码发现传递的id比currentid大导致一直等待超时,超时时间默认为200s(sentry.notification.sync.timeout.ms)。 开启了hdfs-sentry acl同步后,hdfs,sentry,HMS三者间权限同步的消息处理。当突然大批量的目录权限消息需要处理,后台线程处理不过来,消息积压滞后就会出现这个异常。这个异常不影响集群使用,只是会导致create,drop table慢需要等200s,这样等待也是为了追上最新的id。我们这次同时出现了HMS参与同步消息处理的线程被异常退出,导致sentry的sentry_hms_notification_id表数据一直没更新,需要重启HMS。如果积压了太多消息,让它慢慢消费处理需要的时间太长,可能一直追不上,这时可以选择丢掉这些消息。
解决:
①可以通过设置sentry.notification.sync.timeout.ms参数调小超时时间,减小等待时间,积压不多的话可以让它自行消费处理掉。
②丢掉未处理的消息,在sentry的sentry_hms_notification_id表中插入一条最大值(等于当前消息的id,从notification_sequence表中获取) ,重启sentry服务。(notification_log 表存储了消息日志信息)
1 | SELECT * from NOTIFICATION_SEQUENCE |
Hive开启自动获取表上次访问时间(lastAccessTime)
1 | <property> |
Spark
Shuffle异常导致任务失败 报错:org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 1
原因:
shuffle分为shuffle write和shuffle read两部分。 shuffle write的分区数由上一阶段的RDD分区数控制,shuffle read的分区数则是由Spark提供的一些参数控制。 shuffle write可以简单理解为类似于saveAsLocalDiskFile的操作,将计算的中间结果按某种规则临时放到各个executor所在的本地磁盘上。 shuffle read的时候数据的分区数则是由spark提供的一些参数控制。可以想到的是,如果这个参数值设置的很小,同时shuffle read的量很大,那么将会导致一个task需要处理的数据非常大。结果导致JVM crash,从而导致取shuffle数据失败,同时executor也丢失了,看到Failed to connect to host的错误,也就是executor lost的意思。有时候即使不会导致JVM crash也会造成长时间的gc。
解决思路:减少shuffle的数据量和增加处理shuffle数据的分区数
①spark.sql.shuffle.partitions控制分区数,默认为200,根据shuffle的量以及计算的复杂度提高这个值 shuffle并行度
②提高spark.executor.memory
③map side join或是broadcast join来规避shuffle的产生
④分析数据倾斜 解决数据倾斜
⑤增加失败的重试次数和重试的时间间隔 通过spark.shuffle.io.maxRetries控制重试次数,默认是3,可适当增加,例如10。 通过spark.shuffle.io.retryWait控制重试的时间间隔,默认是5s,可适当增加,例如10s。
⑥类似RemoteShuffleService的服务,解决Shuffle单台机器IO瓶颈,记录Shuffle状态,大批量提升Shuffle效率和稳定性。