You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用Kerberos的Hive1.1.0远程元存储Spark1.6.0 SQL查询异常

解决Spark访问Hive表数据时的UnknownHostException: xxx-nameservice错误

从你的错误堆栈和代码来看,问题的核心很明确:你的Spark节点无法解析HDFS高可用(HA)集群中的xxx-nameservice标识。

为什么之前能查看库表但查数据失败?

  • show tables这类操作只需要和Hive Metastore交互,读取元数据信息,不需要访问HDFS;
  • 而select * from tab1需要读取实际存储在HDFS上的表数据,这时候Spark必须能识别HDFS HA的nameservice,并找到对应的NameNode节点。

具体解决方案

1. 同步HDFS HA配置文件到Spark节点

Spark需要Hadoop的core-site.xml和hdfs-site.xml来识别HDFS的HA配置,你需要从Hadoop集群的配置目录(通常是$HADOOP_HOME/etc/hadoop)复制这两个文件到Spark的conf目录下($SPARK_HOME/conf)。

关键配置项示例(根据你的实际集群调整):

  • core-site.xml中需包含:
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://xxx-nameservice</value>
    </property>
    
  • hdfs-site.xml中需包含HA相关配置:
    <!-- 定义nameservice名称 -->
    <property>
        <name>dfs.nameservices</name>
        <value>xxx-nameservice</value>
    </property>
    <!-- 指定该nameservice下的NameNode节点标识 -->
    <property>
        <name>dfs.ha.namenodes.xxx-nameservice</name>
        <value>nn1,nn2</value>
    </property>
    <!-- 每个NameNode的RPC访问地址 -->
    <property>
        <name>dfs.namenode.rpc-address.xxx-nameservice.nn1</name>
        <value>你的nn1主机名:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.xxx-nameservice.nn2</name>
        <value>你的nn2主机名:8020</value>
    </property>
    <!-- 故障转移代理类 -->
    <property>
        <name>dfs.client.failover.proxy.provider.xxx-nameservice</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    

2. 确保Spark节点能解析NameNode主机名

复制完配置后,在Spark节点上ping一下配置中的NameNode主机名(比如你的nn1主机名),如果ping不通:

  • 直接修改Spark节点的/etc/hosts文件,添加主机名和对应IP的映射;
  • 或者确保集群的DNS服务能正确解析这些主机名。

3. Kerberos环境额外配置(如果你的集群启用了Kerberos)

如果是Kerberos认证的集群,还要确保:

  • Spark节点已经获取了有效的Kerberos ticket(可以用kinit命令验证);
  • hdfs-site.xml中包含正确的Kerberos相关配置,比如:
    <property>
        <name>dfs.namenode.kerberos.principal</name>
        <value>hdfs/_HOST@YOUR.REALM</value>
    </property>
    

4. 临时方案:代码中直接设置HDFS配置(不推荐长期使用)

如果暂时无法修改配置文件,也可以在代码中直接添加HDFS HA的配置:

val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
// 添加HDFS HA配置
hiveContext.setConf("fs.defaultFS", "hdfs://xxx-nameservice")
hiveContext.setConf("dfs.nameservices", "xxx-nameservice")
hiveContext.setConf("dfs.ha.namenodes.xxx-nameservice", "nn1,nn2")
hiveContext.setConf("dfs.namenode.rpc-address.xxx-nameservice.nn1", "你的nn1主机名:8020")
hiveContext.setConf("dfs.namenode.rpc-address.xxx-nameservice.nn2", "你的nn2主机名:8020")
hiveContext.setConf("dfs.client.failover.proxy.provider.xxx-nameservice", "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider")

// 原有配置
hiveContext.setConf("hive.metastore.uris", prop.getProperty("hive.metastore.uris"))
// ... 其他Hive配置

hiveContext.sql("use abc")
hiveContext.sql("show tables").show(4)
hiveContext.sql("select * from abc.tab1 limit 10").show(2)

按照以上步骤配置后,应该就能正常读取Hive表的数据了。

内容的提问来源于stack exchange,提问作者Souvik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:15:37