Spark SQL创建Hive表时生成冲突Thrift端点致Hive容器连接失败
问题:Spark连接Hive Metastore时自动添加容器网络后缀导致连接失败
问题现象
使用Docker构建数据湖仓,通过Spark SQL操作Hive库时,已在Spark Session初始化和自定义hive-site.xml中配置hive.metastore.uris为thrift://metastore:9083,但执行DROP SCHEMA、CREATE DATABASE等SQL语句时,Spark自动生成带容器网络后缀的Thrift端点thrift://metastore.data_lakehouse2_lakehouse:9083(其中data_lakehouse2是Compose栈文件夹名,lakehouse是网络名),触发java.net.URISyntaxException错误,无法连接Hive容器。
使用默认Hive 2.3.9内置jar时无此问题,切换为Maven拉取3.1.3版本jar后出现该异常。
相关配置代码
Spark Session初始化代码
from pyspark.sql import SparkSession from pyspark.sql.types import StructType, StructField, IntegerType, StringType import os from pyspark.sql.functions import * from delta import configure_spark_with_delta_pip from delta.tables import DeltaTable spark = SparkSession.builder \ .appName("appname") \ .config("spark.hadoop.fs.s3a.multiobjectdelete.enable", "true") \ .config("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")\ .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \ .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \ .config("spark.hadoop.fs.s3a.endpoint", "http://minio-host:9000") \ .config("spark.hadoop.fs.s3a.access.key", "minio") \ .config("spark.hadoop.fs.s3a.secret.key", "minio123") \ .config("spark.hadoop.fs.s3a.path.style.access", "true") \ .config("spark.hadoop.fs.s3a.connection.ssl.enabled", "false")\ .config("spark.sql.legacy.charVarcharAsString", True)\ .config("spark.sql.sources.partitionOverwriteMode", "dynamic")\ .config("hive.metastore.uris", "thrift://metastore:9083") \ .config("spark.sql.hive.metastore.version","3.1.3")\ .config("spark.sql.hive.metastore.jars","maven") \ .config("hive.exec.dynamic.partition", "true") \ .config("hive.exec.dynamic.partition.mode", "nonstrict")\ .enableHiveSupport() \ .getOrCreate()
hive-site.xml配置
<property> <name>hive.metastore.uris</name> <value>thrift://metastore:9083</value> <description></description> </property>
执行的SQL语句
spark.sql("DROP SCHEMA IF EXISTS test CASCADE") spark.sql("CREATE DATABASE IF NOT EXISTS test") spark.sql("USE test")
原因分析
这是Hive Metastore 3.x版本新增的自动DNS域名解析增强逻辑导致的:
- Hive 3.1.3的Metastore客户端会对配置的短主机名进行反向DNS解析,在Docker容器网络环境下,
metastore会被解析为带网络后缀的完全限定域名(FQDN),客户端会自动将原配置的主机名替换为这个FQDN。 - Hive 2.3.9没有该自动替换逻辑,会直接使用配置的短主机名
metastore发起连接,因此无异常。 - 解析后的FQDN在Spark的URI处理逻辑中被判定为非法格式,最终触发
java.net.URISyntaxException错误。
解决方案
通过添加Hive配置禁用自动DNS解析行为即可解决:
方式1:在Spark Session初始化时添加配置
在Spark构建器中增加以下两行配置:
.config("hive.metastore.use.dns.names", "false") \ .config("hive.metastore.client.capability.check", "false") \
方式2:修改hive-site.xml配置
在hive-site.xml中新增以下配置项:
<property> <name>hive.metastore.use.dns.names</name> <value>false</value> </property> <property> <name>hive.metastore.client.capability.check</name> <value>false</value> </property>
内容的提问来源于stack exchange,提问作者Gianny Wise
相关产品推荐
相关产品推荐

