HDFS_DELEGATION_TOKEN 还原及解决方案

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

## 版本列表

![](https://upload-images.jianshu.io/upload_images/9028759-35c1bf0606261dc5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 测试用例配置

添加 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

```

2. 测试提交

```

...

--conf spark.hadoop.fs.hdfs.impl.disable.cache=true \

--conf mapreduce.job.complete.cancel.delegation.tokens=false \

...

```

3. 测试提交

```

...

--conf mapreduce.job.complete.cancel.delegation.tokens=false \

...

```

4. 测试提交

```

...

--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)

...

```

## 问题发现

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

还有Exector的问题

```

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")

```

因为Spark的`--principal --keytab`会在令牌即将过期的时候帮我们重新续定,如果代码里面加上之后,Spark会读取到ApplicationMaster中用户已经认证了,没有过期是不会续定NodeManager中的Exector的。

如果是开发环境模式,可以加一个判断使用以上两句代码,**简单粗暴**

## 解决方案(二)

使用UserGroupInformation的进程认证方式

```

spark.sparkContext

.parallelize(0 to 1000)

.repartition(10)

.foreachPartition {

iter => {

val hConf = new Configuration

hConf.addResource("hbase-site.xml")

val ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI("hbase-bd@EXAMPLE.COM", "/etc/security/keytabs/hbase.headless.keytab")

ugi.doAs(new PrivilegedAction[Unit] {//在每个Partition认证

override def run(): Unit = {

val logDir = new Path(args(0))

val fs = FileSystem.get(hConf)

if (!fs.exists(logDir)) throw new Exception(logDir.toUri.getPath + " director not exist.")

while (iter.hasNext) {

iter.next()

val logPaths = fs.listFiles(logDir, false)

TimeUnit.MILLISECONDS.sleep(10)

}

}

})

}

}

```

## BUG 7 天后再次出现

上面推导还是有问题,还有望知道BUG解决的小伙伴告知一下。

## 临时解决方案

就是加大过期的时间

---

![](https://upload-images.jianshu.io/upload_images/9028759-a3ea1ec0784f9946.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容