HDFS_DELEGATION_TOKEN 還原及解決方案

HDFS_DELEGATION_TOKEN 這個(gè)BUG在很多文章中都出現(xiàn)著捞慌,講了很多原理,但是只給出了官方引用地扯,完全沒有給出如何解決涯竟,我們線上的業(yè)務(wù)就有著這樣的問題,7天一到馬上出現(xiàn)這問題了空厌,官方明明說這個(gè)bug修復(fù)了呀庐船,因?yàn)槲覀兪褂玫陌姹臼潜容^新的,理論上不會(huì)有這樣的問題才對(duì)嘲更,可是偏偏就有了筐钟,沒辦法,只能硬上了赋朦,花了兩天的時(shí)間找到了解決這個(gè)問題的辦法篓冲,下面會(huì)還原這個(gè)錯(cuò)誤及給出解決方案。

版本列表

測試用例配置

添加 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小時(shí)

...
ticket_lifetime = 1h
...

代碼內(nèi)有kerberos認(rèn)證

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

測試百度跟谷歌中最最最多出現(xiàn)的解決方案

 --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 測試結(jié)果
時(shí)間觀察3分鐘 => 正常
時(shí)間觀察10分鐘 => 正常
時(shí)間觀察30分鐘 => 正常
時(shí)間觀察60分鐘 => 正常
時(shí)間觀察120分鐘 => 正常
測試結(jié)論 => 與1琳拨、2瞭恰、3、4 --conf 配置無關(guān)

好吧狱庇,我已經(jīng)懷疑人生惊畏、可能是我打開的方式不對(duì)

繼續(xù)測試

將認(rèn)證代碼放入run方法內(nèi)

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

時(shí)間觀察3分鐘 => 正常
時(shí)間觀察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)
...

問題發(fā)現(xiàn)

通過幾十遍不斷的調(diào)整位置恶耽、最終確認(rèn)的問題所在
還有Exector的問題

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

是由于以上兩句kerberos認(rèn)證代碼導(dǎo)致的結(jié)果
跟下面的配置沖突了

--principal $principal --keytab $keytab

解決方案(一)

刪除掉下面代碼中的這兩句認(rèn)證即可,使用--principal $principal --keytab $keytab

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

因?yàn)镾park的--principal --keytab會(huì)在令牌即將過期的時(shí)候幫我們重新續(xù)定,如果代碼里面加上之后颜启,Spark會(huì)讀取到ApplicationMaster中用戶已經(jīng)認(rèn)證了偷俭,沒有過期是不會(huì)續(xù)定NodeManager中的Exector的。
如果是開發(fā)環(huán)境模式缰盏,可以加一個(gè)判斷使用以上兩句代碼涌萤,簡單粗暴

解決方案(二)

使用UserGroupInformation的進(jìn)程認(rèn)證方式

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] {//在每個(gè)Partition認(rèn)證
            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 天后再次出現(xiàn)

上面推導(dǎo)還是有問題,還有望知道BUG解決的小伙伴告知一下口猜。

臨時(shí)解決方案

就是加大過期的時(shí)間


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末负溪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子济炎,更是在濱河造成了極大的恐慌川抡,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件须尚,死亡現(xiàn)場離奇詭異崖堤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)耐床,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門密幔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人咙咽,你說我怎么就攤上這事老玛。” “怎么了钧敞?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蜡豹,是天一觀的道長。 經(jīng)常有香客問我溉苛,道長镜廉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任愚战,我火速辦了婚禮娇唯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寂玲。我一直安慰自己塔插,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布拓哟。 她就那樣靜靜地躺著想许,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上流纹,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天糜烹,我揣著相機(jī)與錄音,去河邊找鬼漱凝。 笑死疮蹦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茸炒。 我是一名探鬼主播愕乎,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼壁公!你這毒婦竟也來了妆毕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤贮尖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后趁怔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體湿硝,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年润努,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了关斜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铺浇,死狀恐怖痢畜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鳍侣,我是刑警寧澤丁稀,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站倚聚,受9級(jí)特大地震影響线衫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惑折,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一授账、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惨驶,春花似錦白热、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春乍恐,著一層夾襖步出監(jiān)牢的瞬間评疗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工茵烈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留百匆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓呜投,卻偏偏與公主長得像加匈,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仑荐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容