从 Spark 访问 Hdfs 会给出 TokenCache 错误 无法获取主 Kerberos 主体以用作更新者



我正在尝试运行一个测试Spark脚本,以便将Spark连接到hadoop。脚本如下

from pyspark import SparkContext
sc = SparkContext("local", "Simple App")
file = sc.textFile("hdfs://hadoop_node.place:9000/errs.txt")
errors = file.filter(lambda line: "ERROR" in line)
errors.count()

当我用pyspark运行它时,我会得到

py4j.protocol.Py4JJava错误:调用时出错o21.collect.:java.io.io异常:无法获取主Kerberos用作更新器的主体网址:org.apache.hadop.mapreduce.security.TokenCache.georgentTokensForNamenodesInternal(TokenCache.java:116)网址:org.apache.hadop.mapreduce.security.TokenCache.georgentTokensForNamenodesInternal(TokenCache.java:100)网址:org.apache.hadop.mapreduce.security.TokenCache.georgentTokensForNamenodes(TokenCache.java:80)网址:org.apache.hadop.mapred.FileInputFormat.listStatus(FileInputFormat.java:187)网址:org.apache.hadop.mapred.FileInputFormat.getSplits(FileInputFormat.java:251)网址:org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:140)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:207)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:205)在scala。Option.getOrElse(Option.scala:120)网址:org.apache.spark.rdd.rdd.partitions(rdd.scala:205)网址:org.apache.spark.rdd.MappedRDD.getPartitions(MappedRDD.scala:28)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:207)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:205)在scala。Option.getOrElse(Option.scala:120)网址:org.apache.spark.rdd.rdd.partitions(rdd.scala:205)网址:org.apache.spark.api.python.PythonRDD.getPartitions(PythonRDD.scala:46)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:207)在org.apache.spark.rdd.rdd$$anonfun$partitions$2.apply(rdd.scala:205)在scala。Option.getOrElse(Option.scala:120)网址:org.apache.spark.rdd.rdd.partitions(rdd.scala:205)网址:org.apache.spark.SparkContext.runJob(SparkContext.scala:898)网址:org.apache.spark.rdd.rdd.collect(rdd.scala:608)网址:org.apache.spark.api.java.JavaRDDLike$class.collect(JavaRDDLick.scala:243)网址:org.apache.spark.api.java.JavaRDD.collect(JavaRDD.scala:27)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)位于java.lang.reflect.Method.ioke(Method.java:606)在py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231)在py4j.reflection.ReflectionEngine.reinvoke(ReflectionEngine.java:379)在py4j.Gateway。invoke(Gateway。java:259)在py4j.commands.AbstractCommand.invokeMethod(AbstractCmd.java:132)在py4j.commands.CallCommand.execute(CallCommand.java:79)在py4j.GatewayConnection.run(GatewayConnection.java:207)在java.lang.Thread.run(Thread.java:744)

尽管

  • 我做了一件比基尼和一件klist表明我有正确的代币
  • 当我发布/bin/hadoop fs-lshdfs://hadoop_node.place:9000/errs.txt它显示文件
  • 本地hadoop客户端和spark都有相同的配置文件

spark/conf和hadoop/conf文件夹中的core-site.xml如下(从一个hadoop节点获得)

<configuration>
    <property>
        <name>hadoop.security.auth_to_local</name>
        <value>
            RULE:[1:$1](.*@place)s/@place//
            RULE:[2:$1/$2@$0](.*/node1.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node2.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node3.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node4.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node5.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node6.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node7.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:nobody]
            DEFAULT
        </value>
    </property>
    <property>
        <name>net.topology.node.switch.mapping.impl</name>
        <value>org.apache.hadoop.net.TableMapping</value>
    </property>
    <property>
        <name>net.topology.table.file.name</name>
        <value>/etc/hadoop/conf/topology.table.file</value>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://server.place:9000/</value>
    </property>
    <property>
      <name>hadoop.security.authentication</name>
      <value>kerberos</value>
    </property>
    <property>
      <name>hadoop.security.authorization</name>
      <value>true</value>
    </property>
    <property>
      <name>hadoop.proxyuser.hive.hosts</name>
      <value>*</value>
    </property>
    <property>
      <name>hadoop.proxyuser.hive.groups</name>
      <value>*</value>
    </property>
</configuration>

有人能指出我遗漏了什么吗?

创建了我自己的hadoop集群,以便更好地了解hadoop的工作原理。我修好了。

您必须向Spark提供一个有效的.keytab文件,该文件是为至少对hadoop集群具有读取访问权限的帐户生成的。

此外,还必须为spark提供hdfs集群的hdfs-site.xml。

所以对于我的情况,我必须创建一个keytab文件,当你运行时

klist-k-e-t

在上面你可以看到下面的

主机/fully.qualified.domain.name@REALM.COM

在我的例子中,host是字面上的单词host,而不是变量。此外,在hdfs-site.xml中,您必须提供keytab文件的路径,并说

主机/_HOST@REALM.COM

将是您的帐户。

Cloudera有一篇关于如何做到这一点的非常详细的文章

编辑在用不同的配置玩了一点之后,我认为应该注意以下几点。您必须为spark提供hadoop集群的确切hdfs-site.xml和core-site.xml。否则它将无法工作

相关内容

  • 没有找到相关文章

最新更新