递归地向数据帧添加行

时间:2017-07-17 16:14:06

标签: scala hadoop apache-spark recursion dataframe

我是新来的火花。我有一些json数据来自HttpResponse。我需要将这些数据存储在配置单元表中。每个HttpGet请求都返回一个json,它将是表中的一行。因此,我不得不在hive表目录中将单行写为文件。

但我觉得有太多小文件会降低速度和效率。那么有一种方法可以递归地向Dataframe添加新行并将其一次性写入hive表目录。我觉得这也会减少我的火花代码的运行时间。

示例:

for(i <- 1 to 10){
 newDF = hiveContext.read.json("path")
 df = df.union(newDF)
}
df.write()

我理解数据帧是不可变的。有没有办法实现这个目标?

任何帮助将不胜感激。谢谢。

3 个答案:

答案 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是否为任何端点,以获取所需的所有数据,而不是一次只获取一条记录。