我是新来的火花。我有一些json
数据来自HttpResponse
。我需要将这些数据存储在配置单元表中。每个HttpGet
请求都返回一个json,它将是表中的一行。因此,我不得不在hive表目录中将单行写为文件。
但我觉得有太多小文件会降低速度和效率。那么有一种方法可以递归地向Dataframe
添加新行并将其一次性写入hive表目录。我觉得这也会减少我的火花代码的运行时间。
示例:
for(i <- 1 to 10){
newDF = hiveContext.read.json("path")
df = df.union(newDF)
}
df.write()
我理解数据帧是不可变的。有没有办法实现这个目标?
任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
您大部分时间都在正确的轨道上,您要做的是将多个单个记录作为Seq[DataFrame]
获取,然后通过合并将Seq[DataFrame]
缩减为单个DataFrame
根据您提供的代码:
val BatchSize = 100
val HiveTableName = "table"
(0 until BatchSize).
map(_ => hiveContext.read.json("path")).
reduce(_ union _).
write.insertInto(HiveTableName)
或者,如果您想要随时执行HTTP请求,我们也可以这样做。假设您有一个执行HTTP请求并将其转换为DataFrame的函数:
def obtainRecord(...): DataFrame = ???
您可以采取以下措施:
val HiveTableName = "table"
val OtherHiveTableName = "other_table"
val jsonArray = ???
val batched: DataFrame =
jsonArray.
map { parameter =>
obtainRecord(parameter)
}.
reduce(_ union _)
batched.write.insertInto(HiveTableName)
batched.select($"...").write.insertInto(OtherHiveTableName)
答案 1 :(得分:0)
你显然在滥用Spark。 Apache Spark是分析系统,而不是数据库API。使用Spark来修改Hive数据库没有任何好处。它只会带来严重的性能损失而不会受益于任何Spark功能,包括分布式处理。
相反,您应该直接使用Hive客户端来执行事务操作。
答案 2 :(得分:0)
如果您可以批量下载所有数据(例如使用curl或其他程序的脚本)并将其首先存储在文件中(或许多文件,spark可以一次加载整个目录),那么您可以将该文件(或文件)一次性加载到spark中以进行处理。我还会检查webapi是否为任何端点,以获取所需的所有数据,而不是一次只获取一条记录。