我正在使用Spark实现以下逻辑。
如何将(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
})
问题:
答案 0 :(得分:1)
如何将大数据框分成小数据帧? (重新分区?)
简单的答案是肯定repartion可以是一个解决方案。
挑剔的问题可能是,将数据框重新划分为较小的分区会改善整体操作吗?
数据帧已经在本质上分发。这意味着您对数据框(如join,groupBy,聚合,函数等)执行的操作都将在数据所在的位置执行。但是像join,groupBy,聚合这样的操作需要改组,重新分区将无效
groupBy操作会改组数据框,使不同的组在同一个执行器中。
windowBy中的partitionBy执行与groupBy相同的方式
join操作会以相同的方式对数据进行洗牌。
将table2(将大数据帧作为参数传递给)这样的执行器是否很好?
像你一样传递数据帧并不好。当您在转换中传递数据帧时,执行程序将无法看到table2
。
我建议您使用broadcast variable
你可以这样做
val table2 = sparkContext.broadcast(getTable("table2"))
val result = partitionedTable1.map(x => {
val value = doWork(x, table2.value)
value
})