【问题标题】:Apache Spark not using partition information from Hive partitioned external tableApache Spark 不使用来自 Hive 分区外部表的分区信息
【发布时间】:2019-12-29 12:58:07
【问题描述】:

我有一个在 S3 之上创建的简单 Hive-External 表(文件为 CSV 格式)。当我运行配置单元查询时,它会显示所有记录和分区。

但是,当我在 Spark 中使用同一张表时(其中 Spark SQL 在分区列上有 where 条件),它并没有显示应用了分区过滤器。但是对于 Hive 托管表,Spark 能够使用分区信息并应用分区过滤器。

是否有任何标志或设置可以帮助我在 Spark 中使用 Hive 外部表的分区?谢谢。

更新:

由于某种原因,只有 spark 计划没有显示分区过滤器。但是,当您查看加载的数据时,它只会从分区加载所需的数据。

例如:在 rating=0 时,仅加载一个 1 MB 的文件,当我没有过滤时,它读取所有 3 个分区为 3 MB

【问题讨论】:

  • 如果在对 hive 管理的表的查询中将“where movieid in (10,12)”替换为“where rating=0”会发生什么?我怀疑“PartitionFilters:...”在这种情况下会消失。如果您在“where”子句中仅包含特定分区,则可能不会调用过滤器
  • 啊,hive 管理表中的分区是“movieid”,而不是“rating”,对吧?那时我的推理是错误的
  • @mangusta 我知道混乱会用细节更新问题
  • 你可以尝试将 where 子句值作为字符串而不是 int - 比如 where rating='0'
  • 这里有点不清楚

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


【解决方案1】:

tl; dr 在运行外部表的 sql 之前设置以下内容 spark.sql("set spark.sql.hive.convertMetastoreOrc=true")

行为上的差异不是因为外部/托管表。
行为取决于两个因素
1. 创建表的位置(Hive 或 Spark)
2. 文件格式(我相信是ORC,从截屏来看)

创建表的位置(Hive 或 Spark)

如果表是使用 Spark API 创建的,则将其视为数据源表。
如果表是使用 HiveQL 创建的,则将其视为 Hive 原生表。
这两个表的元数据都存储在 Hive 元存储中,唯一的区别是表的TBLPROPERTIESprovider 字段(describe extended <tblName>)。该属性的值为 orc 或在 Spark 表中为空,在 Hive 中为 hive

spark 如何使用这些信息

当提供者不是hive(数据源表)时,Spark 使用其原生方式处理数据。
如果 provider 是hive,Spark 使用 Hive 代码来处理数据。

文件格式

Spark 提供配置标志以指示引擎使用 Datasource 方式处理流文件格式的数据 = OrcParquet 标志:

Orc

  val CONVERT_METASTORE_ORC = buildConf("spark.sql.hive.convertMetastoreOrc")
    .doc("When set to true, the built-in ORC reader and writer are used to process " +
      "ORC tables created by using the HiveQL syntax, instead of Hive serde.")
    .booleanConf
    .createWithDefault(true)

Parquet

val CONVERT_METASTORE_PARQUET = buildConf("spark.sql.hive.convertMetastoreParquet")
    .doc("When set to true, the built-in Parquet reader and writer are used to process " +
      "parquet tables created by using the HiveQL syntax, instead of Hive serde.")
    .booleanConf
    .createWithDefault(true)

【讨论】:

  • 您可以通过查看计划来确定 Spark 是否将其视为 hive 表 - 如果扫描节点是 HiveTableRelation(first sn-p),Spark 将使用 Hive 流进行处理,否则它是Spark 数据源表
  • 在 Spark 中,Hive 代码流仅针对 orc 和 parquet 触发。对于所有其他格式,Spark 使用其本机代码进行处理
  • @DaRkMaN spark 计划没有显示分区过滤器,但是当您看到 Spark-UI 时,您可以看到执行程序仅根据需要加载数据。请查看带有更多图片的更新问题。
  • 你怎么看是ORC?
  • 显示计划的屏幕截图(标题为partition-demo
【解决方案2】:

在内部和外部表的多个连接中,我也遇到过这种问题。

这些技巧都不起作用,包括:

    spark.sql("set spark.sql.hive.convertMetastoreParquet=false")
    spark.sql("set spark.sql.hive.metastorePartitionPruning=true")
    spark.sql("set spark.sql.hive.caseSensitiveInferenceMode=NEVER_INFER")

任何知道如何解决这个问题的人。

【讨论】:

  • 做了一些测试,外部表不是原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-18
  • 1970-01-01
相关资源
最近更新 更多