【问题标题】:SparkR bottleneck in createDataFrame?createDataFrame 中的 SparkR 瓶颈?
【发布时间】:2015-12-29 12:58:52
【问题描述】:

我是 Spark、SparkR 以及所有与 HDFS 相关的技术的新手。我最近安装了 Spark 1.5.0 并使用 SparkR 运行了一些简单的代码:

Sys.setenv(SPARK_HOME="/private/tmp/spark-1.5.0-bin-hadoop2.6")
.libPaths("/private/tmp/spark-1.5.0-bin-hadoop2.6/R/lib")
require('SparkR')
require('data.table')

sc <- sparkR.init(master="local")
sqlContext <- sparkRSQL.init(sc)
hiveContext <- sparkRHive.init(sc)

n = 1000
x = data.table(id = 1:n, val = rnorm(n))

Sys.time()
xs <- createDataFrame(sqlContext, x)
Sys.time()

代码立即执行。但是,当我将其更改为 n = 1000000 时,大约需要 4 分钟(两次 Sys.time() 调用之间的时间)。当我在端口:4040 的控制台中检查这些作业时,n = 1000 的作业持续时间为 0.2 秒,n = 1000000 的作业持续时间为 0.3 秒。我做错了吗?

【问题讨论】:

  • 由于途中出现了一些意想不到的问题,我花了一段时间(在途中遇到了一些其他错误,更不用说我一直忘记您可以将多么奇怪的东西放在数据框列中)但这应该是在 1.6.0 中解决:SPARK-11086

标签: r apache-spark sparkr


【解决方案1】:

你没有做任何特别错误的事情。这只是不同因素综合作用的结果:

  1. createDataFrame 目前(Spark 1.5.1)实施速度很慢。这是SPARK-8277 中描述的已知问题。
  2. 当前的实现不能很好地与data.table 配合使用。
  3. Base R 相对较慢。聪明的人说这是一个功能而不是一个错误,但它仍然值得考虑。

在解决 SPARK-8277 之前,您无能为力,但您可以尝试两种选择:

  • 使用普通的旧 data.frame 而不是 data.table。使用航班数据集(227496 行,14 列):

    df <- read.csv("flights.csv")
    microbenchmark::microbenchmark(createDataFrame(sqlContext, df), times=3)
    
    ## Unit: seconds
    ##                             expr      min       lq     mean   median
    ##  createDataFrame(sqlContext, df) 96.41565 97.19515 99.08441 97.97465
    ##        uq      max neval
    ##  100.4188 102.8629     3
    

    data.table相比

    dt <- data.table::fread("flights.csv")
    microbenchmark::microbenchmark(createDataFrame(sqlContext, dt), times=3)
    
    ## Unit: seconds        
    ##                             expr      min       lq     mean  median
    ##  createDataFrame(sqlContext, dt) 378.8534 379.4482 381.2061 380.043
    ##        uq     max neval
    ##  382.3825 384.722     3
    
  • 写入磁盘并使用spark-csv 将数据直接加载到Spark DataFrame 而不与R 直接交互。听起来很疯狂:

    dt <- data.table::fread("flights.csv")
    
    write_and_read <- function() {
        write.csv(dt, tempfile(), row.names=FALSE)
        read.df(sqlContext, "flights.csv",
            source = "com.databricks.spark.csv",
            header = "true",
            inferSchema = "true"
        )
    }
    
    ## Unit: seconds
    ##              expr      min       lq     mean   median
    ##  write_and_read() 2.924142 2.959085 2.983008 2.994027
    ##       uq      max neval
    ##  3.01244 3.030854     3
    

我不确定是否真的将可以在 R 中处理的数据推送到 Spark 是否真的有意义,但我们不要纠缠于此。

编辑

此问题应由 Spark 1.6.0 中的 SPARK-11086 解决。

【讨论】:

  • 我喜欢你最后的评论! :)
  • 是的...我在这里可能有偏见,但我觉得 SparkR 从 R 中获得了大部分乐趣,而回报却很少。 Scala API 足够强大,即使在相对较小的数据上也值得考虑,特别是当除了 Breeze 没有惯用的替代方案时。在 Python 中,它是 50-50。但是 SparkR 感觉有点笨拙的数据库驱动程序 :)
  • 您能否详细说明您的第二点,为什么?一个 data.table 是一个 data.frame 并且有一些方法可以访问类似于 data.frame 的列。因此有些不解。另外,关于您的第三点,相对较慢的是什么?在这种情况下进行什么操作?
  • @Arun 当然可以,但让我们把它移到chat
猜你喜欢
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
相关资源
最近更新 更多