如何使用包“sparklyr”在R中实现lapply函数

时间:2018-01-15 14:28:10

标签: r apache-spark parallel-processing sparklyr mclapply

我对Spark很新,我试图在网上寻找一些东西,但我没有找到任何令人满意的东西。

我总是使用命令mclapply运行并行计算,我喜欢它的结构(即,第一个参数用作滚动索引,第二个参数是要并行化的函数,然后是传递给函数的其他可选参数) 。 现在我试图通过Spark做同样的事情,即,我想在Spark集群的所有节点之间分配我的计算。这就是我所学到的以及我认为应该如何构建代码(我正在使用包sparklyr):

  1. 我使用命令spark_connect;
  2. 创建了与Spark的连接
  3. 我使用copy_to在Spark环境中复制我的data.frame并通过其tibble访问它;
  4. 我想实现mclapply的“Spark友好”版本,但我看到包中没有类似的功能(我已经看到spark.lapply中存在函数SparkR {1}}包,但不幸的是它不再在CRAN中。)
  5. 下面是我实现的一个简单的测试脚本,它使用函数mclapply

    #### Standard code that works with mclapply #########
    dfTest = data.frame(X = rep(1, 10000), Y = rep(2, 10000))
    
    .testFunc = function(X = 1, df, str) {
        rowSelected = df[X, ]
        y = as.numeric(rowSelected[1] + rowSelected[2])
        return(list(y = y, str = str))
    }
    
    lOutput = mclapply(X = 1 : nrow(dfTest), FUN = .testFunc, df = dfTest, 
                       str = "useless string", mc.cores = 2)
    
    ######################################################
    
    ###### Similar code that should work with Spark ######
    library(sparklyr)
    sc = spark_connect(master = "local")
    
    dfTest = data.frame(X = rep(1, 10000), Y = rep(2, 10000))
    
    .testFunc = function(X = 1, df, str) {
      rowSelected = df[X, ]
      nSum = as.numeric(rowSelected[1] + rowSelected[2])
      return(list(nSum = nSum, str = str))
    }
    
    dfTest_tbl = copy_to(sc, dfTest, "test_tbl", overwrite = TRUE)
    
    # Apply similar function mclapply to dfTest_tbl, that works with 
    # Spark
    # ???
    ######################################################
    

    如果有人已经为此找到了解决方案,那么它会很棒。其他参考/指南/链接也非常受欢迎。谢谢!

2 个答案:

答案 0 :(得分:4)

<强> sparklyr

spark_apply是您正在寻找的现有功能:

spark_apply(sdf, function(data) {
   ...
})

有关详细信息,请参阅sparklyr文档中的Distributed R

<强> SparkR

使用SparkR使用gapply / gapplyCollect

gapply(df, groupingCols, function(data) {...} schema)

dapply / dapplyCollect

dapply(df, function(data) {...}, schema)

的UDF。请参阅

了解详情。

请注意,与本机Spark代码相比,所有解决方案都要低一些,并且在需要高性能时应该避免使用。

答案 1 :(得分:0)

sparklyr::spark_apply现在可以支持传递一些外部变量,例如模型作为上下文。

这是我的在sparklyr上运行xgboost模型的示例:

bst <- xgboost::xgb.load("project/models/xgboost.model")
res3 <- spark_apply(x = ft_union_price %>% sdf_repartition(partitions = 1500, partition_by = "uid"),
                   f = inference_fn,
                   packages = F,
                   memory = F,
                   names = c("uid",
                               "action_1",
                               "pred"), 
                   context = {model <- bst})