如何保证期货在火花中有效利用集群资源

时间:2018-05-04 10:43:58

标签: scala apache-spark apache-spark-sql resource-utilization

我想在spark集群中运行多个spark SQL并行,这样我就可以利用整个资源集群范围。我正在使用sqlContext.sql(查询)。

我看到了一些示例代码here,如下所示,

val parallelism = 10
val executor = Executors.newFixedThreadPool(parallelism)
val ec: ExecutionContext = ExecutionContext.fromExecutor(executor)
val tasks: Seq[String] = ???
val results: Seq[Future[Int]] = tasks.map(query => {
  Future{
    //spark stuff here
    0
  }(ec)
})
val allDone: Future[Seq[Int]] = Future.sequence(results)
//wait for results
Await.result(allDone, scala.concurrent.duration.Duration.Inf)
executor.shutdown //otherwise jvm will probably not exit 

据我所知, ExecutionContext 计算机器中的可用内核(使用ForkJoinPool)并相应地执行并行操作。但是如果我们考虑火花簇而不是单台机器会发生什么呢?它如何保证完整的集群资源利用率呢?

例如:如果我有一个10节点集群,每4个核心,那么上述代码如何保证将使用40个核心。

编辑: -

假设有2个sql要执行,我们有2种方法可以执行此操作,

  1. 按顺序提交查询,以便第二次查询仅在执行第一次查询后完成。 (因为sqlContext.sql(查询)是同步调用)

  2. 使用Futures并行提交两个查询,以便两个查询将在群集中独立执行并且并行执行 假设有足够的资源(在两种情况下)。

  3. 我认为第二个更好,因为它使用集群中可用的最大资源,如果第一个查询充分利用资源,则调度程序将等待作业完成(取决于策略),这在此是公平的情况下。

    但是,用户9613318提到'增加游泳池大小会让驾驶员饱和' 那么我怎样才能有效地控制线程以获得更好的资源利用率。

1 个答案:

答案 0 :(得分:1)

并行性在这里影响很小,而其他群集资源并不会真正影响该方法。 Futures(或Threads)不用于并行执行,而是用于避免阻塞执行。增加游泳池大小只会使驾驶员饱和。

你应该关注的是Spark in-application scheduling pools并调整narrow(How to change partition size in Spark SQLWhats meaning of partitionColumn, lowerBound, upperBound, numPartitions parameters?)和wide(What should be the optimal value for spark.sql.shuffle.partitions or how do we increase partitions when using Spark SQL?的分区数量)转型。

如果作业完全独立(代码结构表明),可能最好分别使用自己的已分配资源集提交每个作业,并相应地配置集群调度池。