如何在Spark中并行读写多个表?

时间:2015-08-24 22:42:12

标签: scala parallel-processing apache-spark apache-spark-sql

在我的Spark应用程序中,我试图从RDBMS读取多个表,进行一些数据处理,然后将多个表写入另一个RDBMS,如下所示(在Scala中):

val reading1 = sqlContext.load("jdbc", Map("url" -> myurl1, "dbtable" -> mytable1))
val reading2 = sqlContext.load("jdbc", Map("url" -> myurl1, "dbtable" -> mytable2))
val reading3 = sqlContext.load("jdbc", Map("url" -> myurl1, "dbtable" -> mytable3))

// data processing
// ..............

myDF1.write.mode("append").jdbc(myurl2, outtable1, new java.util.Properties)
myDF2.write.mode("append").jdbc(myurl2, outtable2, new java.util.Properties)
myDF3.write.mode("append").jdbc(myurl2, outtable3, new java.util.Properties)

我知道从一个表读取可以使用分区并行。但是,read1,reading2,reading3的读操作似乎是顺序的,myDF1,myDF2,myDF3的写操作也是如此。

如何并行读取多个表(mytable1,mytable2,mytable3)?并且并行写入多个表(我认为是相同的逻辑)?

1 个答案:

答案 0 :(得分:1)

您可以将模式安排为FAIR,它应该并行运行任务。 https://spark.apache.org/docs/latest/job-scheduling.html#scheduling-within-an-application

在应用程序中进行调度 在给定的Spark应用程序(SparkContext实例)中,如果从单独的线程提交多个并行作业,则它们可以同时运行。通过“作业”,在本节中,我们指的是Spark操作(例如,保存,收集)以及需要运行以评估该操作的任何任务。 Spark的调度程序是完全线程安全的,并支持此用例,以支持提供多个请求的应用程序(例如,查询多个用户)。

默认情况下,Spark的调度程序以FIFO方式运行作业。每个工作分为“阶段”(例如地图和减少阶段),第一个工作优先于所有可用资源,而其阶段有任务启动,然后第二个工作获得优先权等。如果工作在头部队列不需要使用整个集群,以后的作业可以立即开始运行,但如果队列头部的作业很大,则后续作业可能会显着延迟。

从Spark 0.8开始,还可以在作业之间配置公平共享。在公平共享下,Spark以“循环”方式在作业之间分配任务,以便所有作业获得大致相等的群集资源份额。这意味着在长时间工作运行时提交的短工作可以立即开始接收资源,并且仍然可以获得良好的响应时间,而无需等待长时间的工作完成。此模式最适合多用户设置。

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.set("spark.scheduler.mode", "FAIR")
val sc = new SparkContext(conf)