并行性:rdd.parallelize(....)vs dataSet.map(...)?

时间:2017-05-24 22:39:04

标签: scala apache-spark

我使用DataFrame / DataSet和RDD实现了Spark应用程序。我将应用程序提交到Spark 2.1.1的本地开发环境。我的电脑有八个 CPU内核。

DateFrame /数据集

val date : LocalDate = ....
val conf = new SparkConf()
val sc = new SparkContext(conf.setAppName("Test").setMaster("local[*]"))
val sqlContext = new org.apache.spark.sql.SQLContext(sc)

val itemListJob = new ItemList(sqlContext, jdbcSqlConn)
import sqlContext.implicits._ 
val processed = itemListJob.run(rc, priority).select("id").map(d => {
  val (a, b) = runJob.run(d, date) // returns a tuple of (int, java.sql.Date), which are the passed parameters.
  s"$a, $b"
})

class ItemList(sqlContext: org.apache.spark.sql.SQLContext, jdbcSqlConn: String) {
  def run(date: LocalDate) = {
    import sqlContext.implicits._ 
    sqlContext.read.format("jdbc").options(Map(
      "driver" -> "com.microsoft.sqlserver.jdbc.SQLServerDriver",
      "url" -> jdbcSqlConn,
      "dbtable" -> s"dbo.GetList('$date')"
    )).load()
    .select("id") 
    .as[Int] 
  }
}
processed.write.text("c:\\temp\\mpa")

RDD

val itemList = itemListJob.run(rc, priority).select("id").rdd.map(r => r(0).asInstanceOf[Int]).collect()

val processed = sc.parallelize(itemList).map(d => {
  runJob.run(d, rc) // returns a tuple of (int, LocalDate), which are the passed parameters.
})
processed.saveAsTextFile("c:\\temp\\mpa")

RDD应用程序拆分并生成了8个文本文件,而Dataframe / DataSet只生成了一个文件。这是否意味着RDD并行运行了8个runJob.run(),而DataFrame / DataSet方法只运行了一次没有并发?

我希望运行主要工作负载并且还将进行jdbc调用的runJob.run()分布式并行运行。

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:2)

是的,生成的文件数量是最后一步中并行性的一个很好的指标。 (我可以想到一些可能不是这种情况的极端情况,但这与此无关)

在本地运行时,

sc.parallelize应根据核心数进行拆分。

但是,在这两种情况下,您只使用1个核心来读取jdbc连接,而在RDD情况下,您还要将数据collect()返回给驱动程序,然后parallelize返回完成任务。

首选方法是使用repartition而非collect,然后使用parallelize。更好的是始终并行做事。在通过jdbc加载数据框的情况下,请查看使用参数partitionColumn, lowerBound, upperBound, numPartitionlink)是否适用,以便从一开始就并行运行。