使用Sparklyr在R中创建Lazy Spark读写Parquet作业

时间:2018-06-14 08:31:05

标签: r apache-spark dplyr sparkr sparklyr

我想创建一个从sql源读取的spark作业(使用' spark_read_jdbc')然后将结果写入一个镶木地板文件(&​​#39; spark_write_parquet')。

对于sql语句中的小增量,需要多次执行此操作。我希望懒惰地创建这个工作,以便多个执行者可以接受这份工作。以下是一些示例玩具代码:

sql = "SELECT * FROM TBL_%s"
for(i in seq(1,10)){
  sql_to_read = sprintf(sql, i)
  optionSet$dbtable = paste0("(", sql_to_read ,") foo")
  TEMP = spark_read_jdbc(sc, "TEMP", options = optionSet, memory = FALSE)
  TEMP = TEMP %>% mutate(id := i)
  TEMP %>% spark_write_parquet(., path = "/TEMP.parquet", mode = "append", partition_by = id)
}

问题是写操作不能延迟执行强制执行串行操作。有没有办法编写这个代码,以便简单地为完整的操作创建一个spark工作,然后当我踢一个' collect'语句多个执行程序将执行操作吗?

1 个答案:

答案 0 :(得分:3)

您始终可以使用代码的结构来完全避免问题。因为所有写入都使用相同的输出表,所以您可以将输入定义为单个联合:

xs <- 1:10
query <- glue::glue("SELECT {xs} AS _id, * FROM TBL_{xs}") %>% 
  glue::collapse(" UNION ALL \n")

然后

optionSet$dbtable <- glue::glue("({query}) tmp")

spark_read_jdbc(sc, "TEMP", options = optionSet, memory = FALSE) %>%
  spark_write_parquet(., path = "/TEMP.parquet", mode = "append", partition_by = id)

您还可以将id用作partitionColumn,并将min(xs) / max(xs)用作lowerBound / upperBoundparallelize reads