0


Hive Delegation Token 揭秘

文章目录


前言

本篇文章是由一次 Hive 集群生产优化而引出的知识点,供大家参考


一、Hive Delegation Token是什么?

要说 Hive Delegation Token,首先简单了解一下 Delegation Token。在网上关于大数据领域里最相关且提到最多的就是 HDFS Delegation Token 有关的文章了,Hive Delegation Token这个提法很少。其实 Hive 的这个东西也是和 HDFS 的有关系,所以咱先提一下 HDFS Delegation Token。HDFS Delegation Token 一言以蔽之就是 Hadoop 里一种轻量级认证方法,客户端创建连接时 NameNode 会创建并保存在内存里,更多的细节大家可以自行百度。^ ^

需要多提一下的是,HDFS 的这套 Delegation Token 机制,不仅仅是 HDFS 的实现,而是为整个大数据领域的框架提供的一套解决方案,其他和 HDFS 有关的组件,也会基于该方案来实现自己的 Delegation Token,比如 Yarn、HBase 等等,当然也包含本篇文章的主人公 Hive,那显而易见,Hive 实现的当然就叫 Hive Delegation Token 了(下文简称 token )。

二、问题产生背景

某一天天气很好,本喵看了一下生产环境 HMS (Hive Metastore) 使用的 Mysql 的监控信息,观察到每隔一个小时,数据库就有一次高 ops 现象,像一日三餐一样非常稳定,高出平时正常值超过 3 倍。于是本喵就从这个现象入手开始排查问题的根因,排查过程枯燥乏味暂且略过,直接来干货上结论!

三、结论

每个 HS2(HiveServer2) 和 HMS 都会起一个守护线程,每隔一个小时该线程都会去清理 MySql 中 Hive 的过期 token。目前存储 token 的表里面长期保持有几万条 token,每次清理时,每个 HS2 和 HMS 都会逐条取出每一条 token 进行过期时间的判断,如果过期就删除。集群中的 HS2 + HMS 的实例数量加起来有几十个,每隔一个小时,这几十个进程的清理操作集中到一起(几十乘以几万就有几百万的数据库操作),导致了上述背景中数据库的毛刺现象。

四、Hive Delegation Token 维护逻辑

感兴趣的童鞋,我们就来一起看下更细节的一些东西。~

当前 Hive 默认的 token 维护策略为:

  1. 新作业(Spark 等)和 HS2 建立新连接的时候新增 token ,默认当前有效时间为 1 天,最大有效时间为 7 天,token 被存储在数据库 hive.delegation_tokens 中
  2. 作业每过 1 个小时更新 token 的有效时间。更新后的有效时间为更新时间点往后 24h
  3. 清理 token 的逻辑为每 1 个小时遍历 delegation_tokens,每个 HS2 和 HMS 都会维护一个清理线程,其逻辑为 3.1. 一次性拿到全部的 TokenIdentifier 先判断是否大于最大有效时间,超过了就删掉 3.2. 没超过再通过 TokenIdentifier 去表 delegation_tokens 中取 TokenInfo ,判断是否大于当前有效时间,超过了就删掉

清理线程的启动和处理逻辑:

实际的清理线程是 ExpiredTokenRemover,是 TokenStoreDelegationTokenSecretManager 的内部类

HiveServer2 和 Hive Metastore 服务,在启动的时候都会启动一个 HadoopThriftAuthBridge 对象,然后会通过这个对象的 startDelegationTokenSecretManager 方法来启动 TokenStoreDelegationTokenSecretManager ,然后在 TokenStoreDelegationTokenSecretManager 的 startThreads 方法里面实例化 ExpiredTokenRemover 线程并启动。

Now show you the code !

protectedclassExpiredTokenRemoverextendsThread{privatelong lastMasterKeyUpdate;privatelong lastTokenCacheCleanup;@Overridepublicvoidrun(){LOGGER.info("Starting expired delegation token remover thread, "+"tokenRemoverScanInterval="+ tokenRemoverScanInterval
        /(60*1000)+" min(s)");while(running){try{long now =System.currentTimeMillis();if(lastMasterKeyUpdate + keyUpdateInterval < now){try{rollMasterKeyExt();
            lastMasterKeyUpdate = now;}catch(IOException e){LOGGER.error("Master key updating failed. "+StringUtils.stringifyException(e));}}if(lastTokenCacheCleanup + tokenRemoverScanInterval < now){removeExpiredTokens();
          lastTokenCacheCleanup = now;}try{Thread.sleep(5000);// 5 seconds}catch(InterruptedException ie){LOGGER.error("InterruptedException received for ExpiredTokenRemover thread "+ ie);}}catch(Throwable t){LOGGER.error("ExpiredTokenRemover thread received unexpected exception. "+ t, t);// Wait 5 seconds too in case of an exception, so we do not end up in busy waiting for// the solution for this exceptiontry{Thread.sleep(5000);// 5 seconds}catch(InterruptedException ie){LOGGER.error("InterruptedException received for ExpiredTokenRemover thread during "+"wait in exception sleep "+ ie);}}}}}/**
 * Remove expired tokens. Replaces logic in {@link AbstractDelegationTokenSecretManager}
 * that cannot be reused due to private method access. Logic here can more efficiently
 * deal with external token store by only loading into memory the minimum data needed.
 */protectedvoidremoveExpiredTokens(){long now =System.currentTimeMillis();Iterator<DelegationTokenIdentifier> i = tokenStore.getAllDelegationTokenIdentifiers().iterator();while(i.hasNext()){DelegationTokenIdentifier id = i.next();if(now > id.getMaxDate()){this.tokenStore.removeToken(id);// no need to look at token info}else{// get token info to check renew dateDelegationTokenInformation tokenInfo = tokenStore.getToken(id);if(tokenInfo !=null){if(now > tokenInfo.getRenewDate()){this.tokenStore.removeToken(id);}}}}}

如上述代码所示,ExpiredTokenRemover 只有两个参数 lastMasterKeyUpdate 和 lastTokenCacheCleanup,
分别和 keyUpdateInterval 和 tokenRemoverScanInterval 配合起作用。其中:

  • keyUpdateInterval 是更新 hive.master_keys 表的时间间隔,lastMasterKeyUpdate 是记录上次更新的时间。master_keys 表里的 MASTER_KEY 是服务于生成 token 的,每个 HS2 维护一个,出于安全策略的考虑需要每天更新一次
  • tokenRemoverScanInterval 是更新清理过期 token 的时间间隔,lastTokenCacheCleanup 是记录上次清理的时间。

五、优化

由于每个 HS2 和 HMS 都会做相同的逻辑,在集群规模比较大的情况下,该操作可以交给部分进程来进行(至少有一个就行)。
目前 Hive 本身没有提供直接关闭该清理线程的入口,所以短期考虑用以下方式实现:

  • 调整清理时间间隔参数 hive.cluster.delegation.token.gc-interval(会覆盖 tokenRemoverScanInterval 的值) 为 long 的最大值,间接关闭该功能

后面考虑对保留清理逻辑的进程,控制其清理过期 token 的频率和时间段,避开业务高峰期。


又 get 到一个知识点,下次见~

标签: hive hadoop

本文转载自: https://blog.csdn.net/weixin_45232029/article/details/135071743
版权归原作者 猫语大数据 所有, 如有侵权,请联系我们删除。

“Hive Delegation Token 揭秘”的评论:

还没有评论