为什么在创建表时会出现“需要 Hive 支持才能创建 Hive 表(AS SELECT)”错误?

G L*_*Lor 7 hive scala apache-spark

尝试创建表时遇到问题。

这是创建表的代码,其中发生异常:

sparkSession.sql(s"CREATE TABLE IF NOT EXISTS mydatabase.students(" +
s"name string," + s"age int)")
Run Code Online (Sandbox Code Playgroud)

这是火花会话配置:

lazy val sparkSession = SparkSession
.builder()
.appName("student_mapping")
.enableHiveSupport()
.getOrCreate()
Run Code Online (Sandbox Code Playgroud)

这是例外:

org.apache.spark.sql.AnalysisException: Hive support is required to 
CREATE Hive TABLE (AS SELECT);;'CreateTable `mydatabase`.`students`,
org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, Ignore
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么会发生这种异常?我还有其他几个使用相同会话配置运行的 spark 程序,运行完美无缺。我正在使用 Scala 2.11 和 Spark 2.3。

Soh*_*ani 5

SparkSession 是 Spark SQL 的入口点。它是您在开发 Spark SQL 应用程序时创建的第一个对象之一。

SessionState 是 Spark SQL 会话之间的状态分离层,包括 SQL 配置、表、函数、UDF、SQL 解析器以及依赖于 SQLConf 的所有其他内容。

SessionState 可用作 SparkSession 的 sessionState 属性

在内部,sessionState 会克隆可选的父 SessionState(如果在创建 SparkSession 时给出)或使用由 spark.sql.catalogImplementation 配置属性定义的 BaseSessionStateBuilder 创建一个新的 SessionState:

org.apache.spark.sql.internal.SessionStateBuilder 的内存中(默认)

org.apache.spark.sql.hive.HiveSessionStateBuilder 的配置单元

对于使用蜂巢,你应该使用类org.apache.spark.sql.hive.HiveSessionStateBuilder,并根据这可以通过设置属性来完成的文档spark.sql.catalogImplementation,以hive创建SparkSession对象时:

val conf = new SparkConf
      .set("spark.sql.warehouse.dir", "hdfs://namenode/sql/metadata/hive")
      .set("spark.sql.catalogImplementation","hive")
      .setMaster("local[*]")
      .setAppName("Hive Example")

val spark = SparkSession.builder()
      .config(conf)
      .enableHiveSupport()
      .getOrCreate()
Run Code Online (Sandbox Code Playgroud)

或者您可以在--conf spark.sql.catalogImplementation=hive将作业提交到集群时传递该属性。


gem*_*len 1

引用

默认情况下,Spark SQL 使用带有 Apache Derby 数据库的 Hive 元存储的嵌入式部署模式。

换句话说,默认情况下 Spark 的 sql 上下文不知道集群上 Hive 管理的任何表。

您需要在 Spark 中使用 Hive 的元存储(Hive 中数据库和表的存储)才能从 Spark 应用程序操作它们。

为此,spark.hadoop.hive.metastore.warehouse.dir如果您使用嵌入式元存储,则需要进行设置,或者hive.metastore.uris如果元存储位于远程数据库中,则需要通过 Thrift 协议访问元存储。

  • 谢谢。看起来你的答案是在正确的道路上。我尝试设置 hive.metastore.uris,但这不起作用,但我最终通过在 Spark 提交中将 CatalogImplementation 设置为 hive 找到了问题的解决方案。``--conf Spark.sql.catalogImplementation=hive`` (2认同)