将数据框拆分为较小的数据框并将大数据框推送到所有执行程序?

时间:2017-07-14 23:23:18

标签: scala apache-spark

我正在使用Spark实现以下逻辑。

  1. 获取50K行的表格结果。
  2. 获取另一张桌子(约30K行)。
  3. 对于(1)和(2)之间的所有组合,做一些工作并获得一个值。
  4. 如何将(2)的数据框推送到所有执行程序和分区(1)并在每个执行程序上运行每个部分?怎么实现呢?

    val getTable(t String) =
      sqlContext.read.format("jdbc").options(Map(
        "driver" -> "com.microsoft.sqlserver.jdbc.SQLServerDriver",
        "url" -> jdbcSqlConn,
        "dbtable" -> s"$t"
      )).load()
      .select("col1", "col2", "col3")
    
    val table1 = getTable("table1")
    val table2 = getTable("table2")
    
    // Split the rows in table1 and make N, say 32, data frames
    val partitionedTable1 : List[DataSet[Row]] = splitToSmallerDFs(table1, 32) // How to implement it?
    
    val result = partitionedTable1.map(x => {
      val value = doWork(x, table2) // Is it good to send table2 to executors like this?
      value
    })
    

    问题:

    1. 如何将大数据框架分成小数据帧? (重新分区?)
    2. 将table2(将大数据帧作为参数传递给)这样的执行器是否很好?

1 个答案:

答案 0 :(得分:1)

  
    

如何将大数据框分成小数据帧? (重新分区?)

  

简单的答案是肯定repartion可以是一个解决方案。

挑剔的问题可能是,将数据框重新划分为较小的分区会改善整体操作吗?

数据帧已经在本质上分发。这意味着您对数据框(如join,groupBy,聚合,函数等)执行的操作都将在数据所在的位置执行。但是像join,groupBy,聚合这样的操作需要改组,重新分区将无效

  1. groupBy操作会改组数据框,使不同的组在同一个执行器中。

  2. windowBy中的partitionBy执行与groupBy相同的方式

  3. join操作会以相同的方式对数据进行洗牌。

  4.   
        

    将table2(将大数据帧作为参数传递给)这样的执行器是否很好?

      

    像你一样传递数据帧并不好。当您在转换中传递数据帧时,执行程序将无法看到table2

    我建议您使用broadcast variable

    你可以这样做

    val table2 = sparkContext.broadcast(getTable("table2"))
    val result = partitionedTable1.map(x => {
      val value = doWork(x, table2.value) 
      value
    })