【问题标题】:Can't query Spark DF from Hive after `saveAsTable` - Spark SQL specific format, which is NOT compatible with Hive`saveAsTable` 后无法从 Hive 查询 Spark DF - Spark SQL 特定格式,与 Hive 不兼容
【发布时间】:2019-12-10 10:59:04
【问题描述】:

我正在尝试将数据框保存为外部表,该表将使用 spark 和可能的 hive 进行查询,但不知何故,我无法使用 hive 查询或查看任何数据。它可以在 spark 中运行。

这是重现问题的方法:

scala> println(spark.conf.get("spark.sql.catalogImplementation"))
hive
scala> spark.conf.set("hive.exec.dynamic.partition", "true")
scala> spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
scala> spark.conf.set("spark.sql.sources.bucketing.enabled", true)
scala> spark.conf.set("hive.exec.dynamic.partition", "true")
scala> spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
scala> spark.conf.set("hive.enforce.bucketing","true")
scala> spark.conf.set("optimize.sort.dynamic.partitionining","true")
scala> spark.conf.set("hive.vectorized.execution.enabled","true")
scala> spark.conf.set("hive.enforce.sorting","true")
scala> spark.conf.set("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
scala> spark.conf.set("hive.metastore.uris", "thrift://localhost:9083")
scala> var df = spark.range(20).withColumn("random", round(rand()*90))
df: org.apache.spark.sql.DataFrame = [id: bigint, random: double]

scala> df.head
res19: org.apache.spark.sql.Row = [0,46.0]                                      
scala> df.repartition(10, col("random")).write.mode("overwrite").option("compression", "snappy").option("path", "s3a://company-bucket/dev/hive_confs/").format("orc").bucketBy(10, "random").sortBy("random").saveAsTable("hive_random")
19/08/01 19:26:55 WARN HiveExternalCatalog: Persisting bucketed data source table `default`.`hive_random` into Hive metastore in Spark SQL specific format, which is NOT compatible with Hive. 

这是我在 hive 中的查询方式:

Beeline version 2.3.4-amzn-2 by Apache Hive
0: jdbc:hive2://localhost:10000/default> select * from hive_random;
+------------------+
| hive_random.col  |
+------------------+
+------------------+
No rows selected (0.213 seconds)

但它在 spark 中工作正常:

scala> spark.sql("SELECT * FROM hive_random").show
+---+------+                                                                    
| id|random|
+---+------+
|  3|  13.0|
| 15|  13.0|
...
|  8|  46.0|
|  9|  65.0|
+---+------+

【问题讨论】:

  • 这个栏目名字很奇怪hive_random.col
  • Spark 可以查询它,因为它只使用 hive 元存储,但 Hive 使用 MapReduce 、 Tez 或其他任何东西。您可以尝试将 Hive 引擎设置为 Spark 并进行测试。
  • @gorros 如何设置 hive 引擎?
  • 我在下面添加了答案。
  • 我建议使用 DDL 创建一个表并运行 . df.repartition(10, col("random")).write.mode("overwrite").option("compression", "snappy").option("path", "s3a://company-bucket/dev/hive_confs/").format("orc").bucketBy(10, "random").sortBy("random") 省略另存为表格

标签: scala apache-spark hadoop hive apache-spark-sql


【解决方案1】:

调用 saveAsTable 后出现警告。这就是暗示所在 -

'以 Spark SQL 特定格式将分桶数据源表 default.hive_random 持久化到 Hive 元存储中,这与 Hive 不兼容。'

'saveAsTable'创建RDD分区而不是Hive分区的原因,解决方法是在调用DataFrame.saveAsTable之前通过hql创建表。

【讨论】:

    【解决方案2】:

    我建议不要尝试几件事。首先,尝试将 hive 执行引擎设置为使用 Spark。

    set hive.execution.engine=spark;

    其次,尝试在 Metastore 中创建外部表,然后将数据保存到该表中。

    【讨论】:

    • 设置引擎无效。我需要使用 DDL 还是使用 Metastore api 创建表?
    • 用 DDL 创建它
    • 也尝试保存到 parquet。也许 Spark 和 Hive 对待 ORC 不同。
    • 出于其他兼容性原因必须将其保存为 orc。
    【解决方案3】:

    Spark 和 Hive 中分桶表的语义不同。
    doc 包含语义差异的详细信息。
    它指出

    Data is written to bucketed tables but the output does not adhere with expected  
    bucketing spec. This leads to incorrect results when one tries to consume the  
    Spark written bucketed table from Hive.
    

    解决方法:如果需要从两个引擎读取,则需要从 Hive 进行写入

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 1970-01-01
      • 2019-02-10
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      相关资源
      最近更新 更多