如何将 DataFrame 持久化到 Hive table?

How to persist a DataFrame to a Hive table?

我在 Cloudera QuickStart VM 上使用 CentOS。我根据另一个问题 How to save DataFrame directly to Hive?.

创建了一个 sbt 管理的 Spark 应用程序

build.sbt

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.5.2"
libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.5.2"
libraryDependencies += "org.apache.spark" % "spark-mllib_2.10" % "1.5.2"
libraryDependencies += "org.apache.spark" % "spark-streaming_2.10" % "1.5.2"
libraryDependencies += "org.apache.spark" %% "spark-hive" % "1.5.2"

我想将 DataFrame 用作 Hive table,如下所示:

 recordDF.registerTempTable("mytempTable")
 hiveContext.sql("create table productstore as select * from mytempTable"); 

我注意到我遇到了错误:

The root scratch dir: /tmp/hive should be writable. Current permissions are: rwx------

我关注了其他问题并为 HDFS 中的 /tmp/hive 设置了 chmod 777

我突然想到 spark 使用本地文件系统 /tmp/hive。

我为本地文件系统做了一个 chmod。

现在我收到错误

org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(message:file:/user/hive/warehouse/productstore is not a directory or unable to create one)

我想在 HDFS hive 仓库中存储一个 DataFrame。

这里有两个问题。

问题 #1 - 权限

On CentOS(或其他 Unix 风格),例如Linux 或 macOS,只需执行以下操作:

chmod -R 777 /tmp/hive

(应该为 OS 上的任何人完成 writable,因为它是一个临时目录)。

问题 #2 - Hive Metastore 目录

由于您使用的是 Cloudera QuickStart VM,因此您使用的是 Spark 2.0 之前的版本(也许是 1.6.3?)。

问题是由于在将 DataFrame 持久化到 Hive 时未指定 path table。

目录 /user/hive/warehouse 默认使用,为了避免写入目录,在使用 option 方法保存到 Hive table 时定义 path 选项或save 加上路径选项。

df.write.option("path", "[path-here]").saveAsTable("tableName")

从 Spark 2.0 开始,以上行将写入本地 Hive 元存储(使用 Derby),该元存储位于当前目录中,如 spark.sql.warehouse.dir Spark 属性 指定的 spark-warehouse .

要升级,请使用 2.0.2(而非 1.5.2)定义您的 Spark 依赖项:

libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.0.2"

(只需要一行就可以让 Spark SQL 支持 Hive)。

然后您可以使用 hive.metastore.warehouse.dirspark.sql.warehouse.dir 设置 Spark 仓库并指向其他 Hive table 所在的 HDFS。