从 Spark 读取 Hive 表作为数据集

Posted

技术标签:

【中文标题】从 Spark 读取 Hive 表作为数据集【英文标题】:Reading Hive table from Spark as a Dataset 【发布时间】:2018-04-09 19:41:59 【问题描述】:

我正在尝试将 spark 中的配置单元表读取为强类型 Dataset,并且我注意到分区没有被修剪,而不是对来自同一个配置单元表的数据帧执行 Spark SQL。

case class States(state: String, country: String)
val hiveDS = spark.table("db1.states").as[States]
//no partition pruning
hiveDS.groupByKey(x=>x.country).count().filter(x=>x._1 == "US")

states 是按国家/地区划分的,因此当我对上述数据集进行计数时,查询会扫描所有分区。但是,如果我这样阅读 -

val hiveDF = spark.table("db1.states")
//correct partition pruning
hiveDF.groupByKey("country").count().filter(x=>x._1 == "US")

分区被正确修剪。谁能解释为什么将表映射到案例类时会丢失分区信息?

【问题讨论】:

【参考方案1】:

TL;DR在第一种情况下缺少分区修剪是预期的行为。

这是因为从优化器的角度来看,与 DataFrame DSL / SQL 使用的操作不同,对对象的任何操作都是一个黑盒子。为了能够优化像 x=> x._1 == "US"x => x.country 这样的功能,Spark 必须应用复杂且不可靠的静态分析,而这样的功能既不存在也不(据我所知)未来计划。

第二种情况不应该编译(没有groupByKey 变体接受字符串),所以无法判断,但一般也不应该修剪,除非你的意思是:

hiveDF.groupBy($"country").count().filter($"country" =!= "US")

另请参阅我对Spark 2.0 Dataset vs DataFrame 的回复。

【讨论】:

谢谢!,我希望如此,但找不到此行为的正确文档。感谢您确认我的假设

以上是关于从 Spark 读取 Hive 表作为数据集的主要内容,如果未能解决你的问题,请参考以下文章

将 Spark 数据集转换为 JSON 并写入 Kafka Producer

Spark 2.1 在读取大量数据集时挂起

无法为大型数据集运行 Spark 作业

Spark迭代/递归算法 - 打破火花谱系

大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集

Apache Spark Java - 如何遍历行数据集并删除空字段