我应该如何配置火花以正确修剪Hive Metastore分区



在将分区过滤器应用于Spark(v2.0.2/2.1.1)时,我遇到了问题,这些数据帧从Hive(v2.1.0)表中读取,并具有30,000多个分区。我想知道推荐的方法是什么,如果有的话,我在做什么,因为当前行为是可靠性问题的大型性能的来源。

启用修剪,我正在使用以下火花/蜂巢属性:

--conf spark.sql.hive.metastorePartitionPruning=true

在Spark-Shell中运行查询时,我可以看到分区获取发生并调用ThriftHiveMetastore.Iface.get_partitions,但这出乎意料地发生了,没有任何过滤:

val myTable = spark.table("db.table")
val myTableData = myTable
  .filter("local_date = '2017-09-01' or local_date = '2017-09-02'")
  .cache
// The HMS call invoked is:
// #get_partitions('db', 'table', -1)

如果我使用更简单的过滤器,则根据需要对分区进行过滤:

val myTableData = myTable
  .filter("local_date = '2017-09-01'")
  .cache
// The HMS call invoked is:
// #get_partitions_by_filter(
//   'db', 'table',
//   'local_date = "2017-09-01"',
//   -1
// )

如果我将过滤器重写以使用范围操作员而不是简单地检查平等:

,则过滤也可以正常工作。
val myTableData = myTable
  .filter("local_date >= '2017-09-01' and local_date <= '2017-09-02'")
  .cache
// The HMS call invoked is:
// #get_partitions_by_filter(
//   'db', 'table',
//   'local_date >= '2017-09-01' and local_date <= '2017-09-02'',
//   -1
// )

在我们的情况下,从性能的角度来看,这种行为是有问题的。正确过滤时,呼叫时间在4分钟与1秒的区域。此外,通常将大量Partition对象加载到每个查询的堆中最终会导致Metastore服务中的内存问题。

似乎围绕某些类型的过滤器结构的解析和解释有一个错误,但是我无法在Spark Jira中找到相关问题。是否有首选方法或特定的火花版本,其中正确应用了所有过滤器的过滤器?还是在构造过滤器时必须使用特定表格(例如范围运算符)?如果是这样,是否在任何地方记录了此限制?

我还没有找到除了(OP)问题中所述重写过滤器之外查询的首选方法。我确实发现Spark对此有了改善的支持,看来我的案件已在Spark 2.3.0中解决。这是我发现的问题的票证:Spark-20331

相关内容

  • 没有找到相关文章