Spark公平调度不起作用

时间:2018-03-16 14:01:38

标签: python apache-spark pyspark scheduling

我正在调查使用spark作为REST API后端的适用性。这个问题似乎是Spark的FIFO调度方法。这意味着如果正在执行大型任务,那么在完成繁重的任务之前,任何小任务都无法完成。根据{{​​3}},公平的调度程序应该解决这个问题。但是,我无法注意到这一切都在改变。我配置调度程序错了吗?

scheduler.xml:

<?xml version="1.0"?>
<allocations>
  <pool name="test">
    <schedulingMode>FAIR</schedulingMode>
    <weight>1</weight>
    <minShare>10</minShare>
  </pool>
</allocations>

我的代码:

$ pyspark --conf spark.scheduler.mode=FAIR --conf spark.scheduler.allocation.file=/home/hadoop/scheduler.xml
>>> import threading
>>> sc.setLocalProperty("spark.scheduler.pool", "test")
>>> def heavy_spark_job():
        # Do some heavy work
>>> 
>>> def smaller_spark_job():
        # Do something simple
>>> 
>>> threading.Thread(target=heavy_spark_job).start()
>>> smaller_spark_job()

较小的火花作业只能在重火花作业的第一项任务不需要所有可用的CPU核心时启动。

2 个答案:

答案 0 :(得分:0)

您只需要为您的任务设置一个不同的池:

默认情况下,每个池都获得群集的相等份额(也与默认池中的每个作业的份额相等),但在每个池中,作业以FIFO顺序运行。例如,如果您为每个用户创建一个池,则意味着每个用户将获得集群的平等份额,并且每个用户的查询将按顺序运行,而不是随后的查询从该用户的较早查询中获取资源。

https://spark.apache.org/docs/latest/job-scheduling.html#default-behavior-of-pools

此外,在PySpark中,子线程无法继承父线程的本地属性,您必须在线程目标函数内设置池。

答案 1 :(得分:0)

我相信,您已经正确地实施了公平调度。由于您没有将smaller_spark_job 作为线程运行,因此线程处理存在问题。因此,它首先等待 heavy_spark_job 完成。应该像下面这样。

threading.Thread(target=heavy_spark_job).start()

threading.Thread(target= smaller_spark_job).start()

此外,my post 可以帮助您从 Spark UI 验证 FAIR 调度。