将 Spark Dataframe 写入 HDP2.6 中的 Hive 可访问表

Posted

技术标签:

【中文标题】将 Spark Dataframe 写入 HDP2.6 中的 Hive 可访问表【英文标题】:Write Spark Dataframe to Hive accessible table in HDP2.6 【发布时间】:2020-05-21 14:27:02 【问题描述】:

我知道已经有很多关于从 Spark 写信给 HIVE 的答案,但似乎没有一个对我有用。所以首先是一些背景。这是一个较旧的集群,运行 HDP2.6,即 Hive2 和 Spark 2.1。

这里是一个示例程序:

case class Record(key: Int, value: String)

val spark = SparkSession.builder()
    .appName("Test App")
    .config("spark.sql.warehouse.dir", "/app/hive/warehouse")
    .enableHiveSupport()
    .getOrCreate()

val recordsDF = spark.createDataFrame((1 to 100).map(i => Record(i, s"val_$i")))
records.write.saveAsTable("records_table")

如果我登录到 spark-shell 并运行该代码,Hive 中会出现一个名为 records_table 的新表。但是,如果我将该代码部署在一个 jar 中,并使用 spark-submit 将其提交到集群,我将看到该表显示在与所有其他 HIVE 表相同的 HDFS 位置,但 HIVE 无法访问它。

我知道在 HDP 3.1 中您必须使用 HiveWarehouseConnector 类,但我在 HDP 2.6 中找不到任何引用。有些人提到了 HiveContext 类,而另一些人则说只使用 SparkSessionBuilder 中的enableHiveSupport 调用。我尝试了这两种方法,但似乎都不起作用。我试过saveAsTable。我试过insertInto。我什至尝试过创建一个临时视图,然后是 hiveContext.sql("create table if not exists mytable as select * from tmptable")。每次尝试时,我都会在 hdfs:/apps/hive/warehouse 中获得一个 parquet 文件,但我无法从 HIVE 本身访问该表。

【问题讨论】:

【参考方案1】:

根据提供的信息,我建议您这样做,

    创建 Spark 会话,enableHiveSupport 是必填项,
val spark = SparkSession.builder()
    .appName("Test App")
    .enableHiveSupport() 
    .getOrCreate()
    接下来,通过spark.sql对表结果表执行DDL,
val ddlStr: String =
    s"""CREATE EXTERNAL TABLE IF NOT EXISTS records_table(key int, value string)
                 |ROW FORMAT SERDE
                 |  'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
                 |STORED AS INPUTFORMAT
                 |  'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
                 |OUTPUTFORMAT
                 |  'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
                 |LOCATION '$hdfsLocation'""".stripMargin

spark.sql(ddlStr)
    根据您的用例编写数据,
val recordsDF = spark.createDataFrame((1 to 100).map(i => Record(i, s"val_$i")))
recordsDF.write.format("orc").insertInto("records_table")

注意事项:

    spark-shell 和 spark-submit 的工作方式相似 可以在 DDL 中定义分区,因此在写入数据帧时不要使用partitionBy。 不支持分桶/集群。

希望这会有所帮助/干杯。

【讨论】:

我会试试这个,让你知道

以上是关于将 Spark Dataframe 写入 HDP2.6 中的 Hive 可访问表的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL - 如何将 DataFrame 写入文本文件?

Spark:将DataFrame写入Mysql

将 spark DataFrame 写入表

Spark - 如何将约 20TB 的数据从 DataFrame 写入配置单元表或 hdfs?

Spark 2.2.0独立模式将Dataframe写入本地单节点Kafka时出错

将 Spark DataFrame 写入 Hive 表时的内存分配问题