HDFS_DELEGATION_TOKEN 还原及解决方案

11 篇文章 0 订阅
9 篇文章 3 订阅

HDFS_DELEGATION_TOKEN 这个BUG在很多文章中都出现着,讲了很多原理,但是只给出了官方引用地扯,完全没有给出如何解决,我们线上的业务就有着这样的问题,7天一到马上出现这问题了,官方明明说这个bug修复了呀,因为我们使用的版本是比较新的,理论上不会有这样的问题才对,可是偏偏就有了,没办法,只能硬上了,花了两天的时间找到了解决这个问题的办法,下面会还原这个错误及给出解决方案。

版本列表

HDP

测试用例配置

添加 hdfs-site.xml 配置

dfs.namenode.delegation.key.update-interval=60000 #1分钟
dfs.namenode.delegation.token.max-lifetime=180000 #3分钟
dfs.namenode.delegation.token.renew-interval=60000 #1分钟

修改 /etc/krb5.conf ticket过期为1小时

...
ticket_lifetime = 1h
...

代码内有kerberos认证

class App {
  System.setProperty("java.security.krb5.conf", "/etc/krb5.conf")
  System.setProperty("sun.security.krb5.debug", "false")
  val hConf = new Configuration
  hConf.addResource("hbase-site.xml")
  UserGroupInformation.setConfiguration(hConf)
  UserGroupInformation.loginUserFromKeytab("hbase-bd@EXAMPLE.COM", "/etc/security/keytabs/hbase.headless.keytab")

  val sparkConf = new SparkConf()
    //      .setMaster("local[12]")
    .setAppName("HDFS_DELEGATION_TOKEN")
  val spark = SparkSession
    .builder
    .config(sparkConf)
    .getOrCreate()
  hConf.set("hbase.mapreduce.inputtable", "test_log")
  def run(args: Array[String]): Unit = {
    val sc = spark.sparkContext
    import spark.implicits._

    val userRDD: RDD[Log] = sc.newAPIHadoopRDD(
      hConf,
      classOf[TableInputFormat],
      classOf[ImmutableBytesWritable],
      classOf[Result]
    ).flatMap {
      rdd => {
        val map = HbaseUtil.result2Map(rdd._2)
        val log = Log(
          map.get("uid")
        )
        Array(log)
      }
    }

    userRDD.toDS().cache().createTempView("log")

    spark.sql(
      """select * from log""".stripMargin)
      .show(false)

    spark.catalog.dropTempView("log")
    userRDD.unpersist()
  }
}
case class Log(uid: String)
object App {
  def main(args: Array[String]): Unit = {
    val app = new App()
    while (true) {
      app.run(args)
      TimeUnit.MINUTES.sleep(3)
    }
  }
}

测试百度跟谷歌中最最最多出现的解决方案

 --conf spark.hadoop.fs.hdfs.impl.disable.cache=true
 --conf mapreduce.job.complete.cancel.delegation.tokens=false
  1. 测试提交
spark-submit --master yarn \
 --class com.dounine.hbase.App \
 --executor-memory 1g \
 --driver-memory 1g \
 --keytab /etc/security/keytabs/hbase.headless.keytab \
 --principal hbase-bd@EXAMPLE.COM \
 build/libs/hdfs-token-1.0.0-SNAPSHOT-all.jar
  1. 测试提交
...
 --conf spark.hadoop.fs.hdfs.impl.disable.cache=true \
 --conf mapreduce.job.complete.cancel.delegation.tokens=false \
...
  1. 测试提交
...
 --conf mapreduce.job.complete.cancel.delegation.tokens=false \
...
  1. 测试提交
...
 --conf spark.hadoop.fs.hdfs.impl.disable.cache=true \
...

1,2,3,4 测试结果
时间观察3分钟 => 正常
时间观察10分钟 => 正常
时间观察30分钟 => 正常
时间观察60分钟 => 正常
时间观察120分钟 => 正常
测试结论 => 与1、2、3、4 --conf 配置无关

好吧,我已经怀疑人生、可能是我打开的方式不对

继续测试

将认证代码放入run方法内

def run(args: Array[String]): Unit = {
  System.setProperty("java.security.krb5.conf", "/etc/krb5.conf")
  System.setProperty("sun.security.krb5.debug", "false")
  val hConf = new Configuration
  hConf.addResource("hbase-site.xml")
  UserGroupInformation.setConfiguration(hConf)
  UserGroupInformation.loginUserFromKeytab("hbase-bd@EXAMPLE.COM", "/etc/security/keytabs/hbase.headless.keytab")

  val sparkConf = new SparkConf()
    //      .setMaster("local[12]")
    .setAppName("HDFS_DELEGATION_TOKEN")
  val spark = SparkSession
    .builder
    .config(sparkConf)
    .getOrCreate()

  hConf.set("hbase.mapreduce.inputtable", "test_log")
....

时间观察3分钟 => 正常
时间观察6分钟 => 异常

18/12/29 16:50:31 ERROR AsyncEventQueue: Listener EventLoggingListener threw an exception
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.token.SecretManager$InvalidToken): token (token for hbase: HDFS_DELEGATION_TOKEN owner
=hbase-bd@EXAMPLE.COM, renewer=yarn, realUser=, issueDate=1546072104965, maxDate=1546072704965, sequenceNumber=15985, masterKeyId=748) is expired, curr
ent time: 2018-12-29 16:32:29,829+0800 expected renewal time: 2018-12-29 16:31:24,965+0800
        at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1497)
        at org.apache.hadoop.ipc.Client.call(Client.java:1443)
        at org.apache.hadoop.ipc.Client.call(Client.java:1353)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:228)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:116)
        at com.sun.proxy.$Proxy11.fsync(Unknown Source)
        at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.fsync(ClientNamenodeProtocolTranslatorPB.java:980)
        at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:422)
        at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeMethod(RetryInvocationHandler.java:165)
        at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invoke(RetryInvocationHandler.java:157)
        at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeOnce(RetryInvocationHandler.java:95)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:359)
        at com.sun.proxy.$Proxy12.fsync(Unknown Source)
...

问题发现

通过几十遍不断的调整位置、最终确认的问题所在

UserGroupInformation.setConfiguration(hConf)
UserGroupInformation.loginUserFromKeytab("hbase-bd@EXAMPLE.COM", "/etc/security/keytabs/hbase.headless.keytab")

是由于以上两句kerberos认证代码导致的结果
跟下面的配置冲突了

--principal $principal --keytab $keytab

解决方案

删除掉代码中的这两句认证即可,使用--principal $principal --keytab $keytab

UserGroupInformation.setConfiguration(hConf)
UserGroupInformation.loginUserFromKeytab("hbase-bd@EXAMPLE.COM", "/etc/security/keytabs/hbase.headless.keytab")

开发环境,可以加一个判断使用以上两句代码,简单粗暴

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误提示表示 Hadoop 找不到正确的 HDFS 安装路径。你需要检查 Hadoop 配置文件中的 hadoop_hdfs_home 参数是否正确设置,或者确认 HDFS 是否已经正确安装并设置了环境变量。 ### 回答2: Hadoop 是一款大数据处理框架,需要依赖 Hadoop HDFS 存储系统。在配置 Hadoop 环境时,需要设置环境变量 HADOOP_HDFS_HOME,以指定 Hadoop HDFS 的安装路径。当出现 "error: invalid hadoop_hdfs_home" 错误时,意味着系统无法识别该环境变量,即 Hadoop HDFS 安装路径无效。 解决该问题的方法是检查环境变量的设置是否正确。首先在命令行界面输入 echo $HADOOP_HDFS_HOME 命令,以检查系统是否能识别该环境变量。如果该命令无法输出正确的路径,则需要修改环境变量的设置。 可以在 ~/.bashrc 或 ~/.bash_profile 文件中添加以下环境变量设置语句: export HADOOP_HDFS_HOME=/path/to/hadoop-hdfs 其中,/path/to/hadoop-hdfs 是 Hadoop HDFS 的安装路径。设置好这个环境变量之后,可以输入 source ~/.bashrc 或 source ~/.bash_profile 命令,以使环境变量的改动生效。 另外,还可通过设置 Hadoop 的配置文件来修改 Hadoop HDFS 的安装路径。可以在 Hadoop 配置文件 core-site.xml 中添加以下配置: <property> <name>hadoop.hdfs.home</name> <value>/path/to/hadoop-hdfs</value> </property> 在以上配置中,/path/to/hadoop-hdfs 是 Hadoop HDFS 的安装路径。保存好配置文件后,重新启动 Hadoop,即可解决 "error: invalid hadoop_hdfs_home" 错误。 ### 回答3: 这个错误信息意味着在运行hadoop相关命令时,系统无法找到指定的hadoop_hdfs_home环境变量。hadoop_hdfs_home是一个关键的环境变量,用于指定hadoop分布式文件系统(HDFS)的安装目录。如果系统无法找到或者无法识别该环境变量,就会出现invalid错误提示。 要解决这个问题,可以尝试以下步骤: 1.检查hadoop_hdfs_home环境变量是否正确设置,可以通过运行echo $hadoop_hdfs_home命令来确认该环境变量的值是否正确。 2.如果hadoop_hdfs_home环境变量未设置,可以通过手动设置该变量或者运行hadoop-env.sh脚本来设置该变量。 3.如果hadoop_hdfs_home环境变量设置正确,但仍然无法正常运行hadoop相关命令,可以尝试重新安装hadoop,并确保正确配置了环境变量。 4.最后,如果你还是无法解决这个问题,可以查看系统日志文件或运行hadoop日志命令来查找更详细的信息和错误提示,以帮助你进一步解决该问题。 总之,如果出现invalid hadoop_hdfs_home错误提示,需要确认hadoop_hdfs_home环境变量设置是否正确,并根据具体情况采取适当措施,以解决此问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值