Spark 3.1通过spark-submit配置Hive Metastore失败问题排查
Spark 3.1通过spark-submit配置Hive元数据的问题
背景
使用Spark 3.1,要求仅通过spark-submit命令的--conf参数配置Hive元数据信息,禁止在代码内配置。
代码内配置可正常运行的情况
代码中显式启用Hive支持并配置参数,提交命令无需额外conf:
spark = SparkSession.builder.appName("redacted-sprak31") \ .enableHiveSupport()\ .config("spark.sql.warehouse.dir", "hdfs://" + hdfs_host + ":8020/user/hive/warehouse")\ .config("hive.metastore.uris", "thrift://" + hdfs_host + ":9083") \ .config("spark.sql.hive.metastore.jars.path", "file:///spark_jars/var/hive_jars/*.jar" ) \ .config("spark.sql.hive.metastore.version", "MYVERSION") \ .config("spark.sql.hive.metastore.jars", "path") \ .config("spark.sql.catalogImplementation", "hive") \ .getOrCreate()
提交命令:
spark-submit \ --py-files={file} local://__main__.py
移至spark-submit --conf后的异常情况
将所有配置移到--conf参数中,代码简化为仅创建SparkSession:
提交命令:
spark-submit \ --conf spark.sql.warehouse.dir="hdfs://${hdfs_host}:8020/user/hive/warehouse" \ --conf hive.metastore.uris="thrift://${hdfs_host}:9083" \ --conf spark.sql.hive.metastore.jars.path="file:///spark_jars/var/hive_jars/*.jar" \ --conf spark.sql.hive.metastore.version="MYVERSION" \ --conf spark.sql.hive.metastore.jars="path" \ --conf spark.sql.catalogImplementation="hive" \ --py-files={file} local://__main__.py
简化后的代码:
spark = SparkSession.builder.appName("redacted-sprak31") \ .getOrCreate()
执行SQL语句select * from DB.TABLE limit 10时抛出错误:
Traceback (most recent call last): File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code exec(code, run_globals) File "/sandbox/__main__.py", line 12, in <module> df = spark.sql("select * from db.table limit 10") File "/usr/local/lib/python3.7/site-packages/pyspark/sql/session.py", line 723, in sql return DataFrame(self._jsparkSession.sql(sqlQuery), self._wrapped) File "/usr/local/lib/python3.7/site-packages/py4j/java_gateway.py", line 1305, in __call__ answer, self.gateway_client, self.target_id, self.name) File "/usr/local/lib/python3.7/site-packages/pyspark/sql/utils.py", line 117, in deco raise converted from None pyspark.sql.utils.AnalysisException: Table or view not found: db.table; line 1 pos 14; 'GlobalLimit 10 +- 'LocalLimit 10 +- 'Project [*] +- 'UnresolvedRelation [db, table], [], false
疑问
- 为何通过--conf传递参数与代码内配置的行为不一致?
- 需要补充哪些配置才能让Spark正常连接Hive元数据?
解答
问题1:行为不一致的核心原因
差异根源在于代码中调用了.enableHiveSupport(),而仅用--conf配置时未触发Hive支持的初始化逻辑:
- 代码内调用
.enableHiveSupport()时,Spark会主动加载Hive Catalog的初始化流程,绑定Hive元数据服务,即使配置了spark.sql.catalogImplementation="hive",这个方法还会触发额外的Hive环境初始化步骤,确保参数生效。 - 仅通过--conf传递参数时,若代码中没有
.enableHiveSupport(),Spark默认不会启用Hive支持——即使配置了Hive相关conf,也无法正确初始化Hive Catalog,导致无法识别Hive中的库表。
另外,部分Hive配置参数的生效时机在SparkSession初始化早期,代码内配置是直接在构建过程中注入,优先级和加载顺序更可靠;而--conf参数需要确保在Session启动前被正确解析加载,若变量替换(如${hdfs_host})失败,也会导致参数失效。
问题2:修复方案及补充配置
方案1:代码中保留.enableHiveSupport()
这是最直接的解决方式,即使所有参数通过--conf传递,代码中仍需调用该方法触发Hive支持:
spark = SparkSession.builder.appName("redacted-sprak31") \ .enableHiveSupport()\ .getOrCreate()
该方法会告诉Spark启用Hive Catalog,配合--conf中的参数即可正常连接元数据。
方案2:优化--conf参数(无需修改代码)
若不想修改代码,需检查并补充以下配置:
- 确认
spark.sql.catalogImplementation参数正确设置为hive,该参数决定Spark使用Hive Catalog而非默认的内存Catalog。 - 验证
${hdfs_host}变量替换是否生效:提交命令前执行echo ${hdfs_host},确认已解析为实际主机名。 - 补充
spark.hadoop.hive.metastore.uris参数:部分Spark版本中,Hive元数据URI需要加spark.hadoop.前缀,即--conf spark.hadoop.hive.metastore.uris="thrift://${hdfs_host}:9083",避免参数不被Hive客户端识别。 - 确保
spark.sql.hive.metastore.jars和spark.sql.hive.metastore.jars.path指向的Hive Jar包路径正确、权限可访问——Spark依赖这些Jar包连接Hive元数据服务。
验证步骤
- 提交前打印
${hdfs_host}确认变量赋值正确。 - 查看Spark日志,检查Hive元数据服务的连接日志,确认无连接失败信息。
- 执行
spark.sql("show databases"),验证是否能获取Hive中的数据库列表。
内容的提问来源于stack exchange,提问作者Itération 122442
相关产品推荐
相关产品推荐

