如何将 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.dir
或 spark.sql.warehouse.dir
设置 Spark 仓库并指向其他 Hive table 所在的 HDFS。
我在 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.dir
或 spark.sql.warehouse.dir
设置 Spark 仓库并指向其他 Hive table 所在的 HDFS。