Spark SQL:HiveContext 不要忽略标头
Posted
技术标签:
【中文标题】Spark SQL:HiveContext 不要忽略标头【英文标题】:Spark SQL : HiveContext don't ignore header 【发布时间】:2016-07-25 11:30:25 【问题描述】:我有一个 spark Job,它从外部 Hive 表中读取数据,并在另一个内部 Hive 表中进行一些转换和重新保存数据
val sparkConf = new SparkConf().setAppName("Bulk Merge Daily Load Job")
val sparkContext = new SparkContext(sparkConf)
val sqlContext = new HiveContext(sparkContext)
// Data Ingestion
val my_df = sqlContext.sql("select * from test")
// Transformation
...
...
// Save Data into Hive
my_df.write.format("orc")
.option("orc.compress","SNAPPY")
.mode(SaveMode.Overwrite)
.saveAsTable("my_internal_table")
外部表是使用 tblproperties
行创建的:
tblproperties ("skip.header.line.count"="1");
我的问题是我在my_internal_table
表的行中发现了一个表示列名称的附加行。
我猜这与issue有关:
我正在使用火花1.6.0
你能帮我解决这个问题吗:
1.6.0
中是否仍然存在此错误?
有什么简单的方法可以避免这种情况吗?
PS:我正在处理大文件 > 10Go。
提前感谢您的回复。
【问题讨论】:
JIRA 仍然“未解决”,很明显没有人在处理它,所以你为什么要问?只需找到解决方法... 您找到解决方案了吗?我有同样的问题 【参考方案1】:我遇到了同样的问题,但如果你将同一张表保存为 ORC,它应该可以工作。只需创建一个与原始表具有相同架构的新表,但将格式设置为 ORC。然后将原始表中的数据回填到ORC中。
当你从 Spark 读取 ORC 表时,它不应该带入标题行。
希望有帮助!
【讨论】:
【参考方案2】:我有一个解决这个限制的方法,虽然它有点贵,但可以嵌入。
scala> val dfData1 = spark.sql("select * from db.mytable")
scala> dfData1.show()
+---+----+
| id|name|
+---+----+
| id|name|
| 1| Sam|
| 2| Pam|
| id|name|
| 3| Jim|
+---+----+
scala> val fileHeader = dfData1.head.getString(0)
fileHeader: String = id
scala> val dfRealData = dfData1.filter(col(dfData1.columns(0)) =!= fileHeader)
dfRealData: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [id: string, name: string]
scala> dfRealData.show()
+---+----+
| id|name|
+---+----+
| 1| Sam|
| 2| Pam|
| 3| Jim|
+---+----+
希望对某人有所帮助。
【讨论】:
【参考方案3】:可能的解决方法:
通过JDBC 连接到 HiveServer2 并让 Hive 进行反序列化 - 获得正确的 CLASSPATH 可能会很麻烦,可能无法处理开箱即用的并行化数据量... 直接读取 CSV,使用“old school” CSV 解析器,并找到跳过标题的方法(例如,参见that question)——old school,是的 直接读取 CSV,使用带有选项“header”的Spark-CSV plugin——显然这是要走的路(但请注意对 Apachecommons-csv.jar
的依赖,应该在文档中明确说明... )
请注意,当直接点击 CSV 文件时,您将失去让 Hive Metastore 隐藏实际 HDFS 目录(或目录,以防表已分区)的好处——因此您又回到了硬编码代码中的路径。
或者,如果您想要更便携的解决方案,您可以使用Hive Java API 到connect to the MetaStore,导航到您想要的表(可能还有它的分区)的StorageDescriptor,获取HDFS(列表)目录,然后点击其中的文件。你要进入那个任务吗,年轻的圣骑士……? B-)
【讨论】:
以上是关于Spark SQL:HiveContext 不要忽略标头的主要内容,如果未能解决你的问题,请参考以下文章
Spark HiveContext 使用 sql 方法应用 IN 操作
Spark SQL HiveContext - saveAsTable 创建错误的架构
Spark SQL(通过 HiveContext 进行 Hive 查询)总是创建 31 个分区
使用 spark hivecontext 读取外部 hive 分区表的问题