从 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