Spark系列(七)Master中的资源调度

资源调度

schedule

说明:

Application的调度算法有两种,分别为spreadOutApps和非spreadOutApps

spreadOutApps

  • 在spark-submit脚本中,可以指定要多少个executor,executor需要多少个cpu及多少内存,基于该机制,最后executor的实际数量,以及每个executor的cpu可能与配置是不一样的。
  • 因为spreadOutApps调度算法的总是基于总CPU总和来分配,比如要求3个executor每个要3个CPU,如果有9个worker每个有1个CPU,因为总共要分配9个core,所以每个worker分配一个core然后每个worker启动一个executor
  • 最后启动9个executor每个executor1个cput core

非spreadOutApps

  • 每个application都尽可能分配到尽量少的worker上,比如总共有10个worker,每个有10个core app总共要分配20个core,那么其实只会分配到两个worker上,每个worker都占满10个core.

 

Schdule方法源码分析

/**
   * Schedule the currently available resources among waiting apps. This method will be called
   * every time a new app joins or resource availability changes.
   */
  private def schedule() {
    // 判断master状态,不为ALIVE时直接返回
    if (state != RecoveryState.ALIVE) { return }
 
    // First schedule drivers, they take strict precedence over applications
10      // Randomization helps balance drivers
11      // 获取状态为ALIVE的worker,并且随机打乱
12      val shuffledAliveWorkers = Random.shuffle(workers.toSeq.filter(_.state == WorkerState.ALIVE))
13      // 可用worker数量
14      val numWorkersAlive = shuffledAliveWorkers.size
15      var curPos = 0
16   
17      // diriver调度过程(yarn-client模式下)
18      for (driver <- waitingDrivers.toList) { // iterate over a copy of waitingDrivers
19        // We assign workers to each waiting driver in a round-robin fashion. For each driver, we
20        // start from the last worker that was assigned a driver, and continue onwards until we have
21        // explored all alive workers.
22        var launched = false
23        var numWorkersVisited = 0
24        // 判读还有可用的worker且Driver还未启动
25        while (numWorkersVisited < numWorkersAlive && !launched) {
26          val worker = shuffledAliveWorkers(curPos)
27          numWorkersVisited += 1
28          // 判断当前worker空闲内存是否大于等于driver需要的内存,且Worker空闲的core数量大于等于dirver需要的core的数量
29          if (worker.memoryFree >= driver.desc.mem && worker.coresFree >= driver.desc.cores) {
30            // 启动driver
31            launchDriver(worker, driver)
32            waitingDrivers -= driver
33            launched = true
34          }
35          curPos = (curPos + 1) % numWorkersAlive
36        }
37      }
38   
39      // Right now this is a very simple FIFO scheduler. We keep trying to fit in the first app
40      // in the queue, then the second app, etc.
41      // spreadOutApps调度方式
42      if (spreadOutApps) {
43        // Try to spread out each app among all the nodes, until it has all its cores
44        // 遍历需要调度的app(Application),且该app中的core还需要调度
45        for (app <- waitingApps if app.coresLeft > 0) {
46          val usableWorkers = workers.toArray.filter(_.state == WorkerState.ALIVE)
47            .filter(canUse(app, _)).sortBy(_.coresFree).reverse
48          // 可用worker的数量
49          val numUsable = usableWorkers.length
50          // 存放app 需要分配core的结果
51          val assigned = new Array[Int](numUsable) // Number of cores to give on each node
52          // 获取Application剩余需要分配的cpu数量与worker总共可用cpu数量中的最小值
53          var toAssign = math.min(app.coresLeft, usableWorkers.map(_.coresFree).sum)
54          var pos = 0
55          while (toAssign > 0) {
56            // 如果worker空闲的cpu数量大于已经分配出去的cpu数量,那么woker还可继续分配cpu
57            if (usableWorkers(pos).coresFree - assigned(pos) > 0) {
58              // 还需分配core的总数量减1
59              toAssign -= 1
60              // 在已分配app core结果集中加1
61              assigned(pos) += 1
62            }
63            pos = (pos + 1) % numUsable
64          }
65          // Now that we've decided how many cores to give on each node, let's actually give them
66          for (pos <- 0 until numUsable) {
67            if (assigned(pos) > 0) {
68              // 根据WorkerInfo和所需的core构建ExecutorDesc
69              val exec = app.addExecutor(usableWorkers(pos), assigned(pos))
70              // 启动Executor
71              launchExecutor(usableWorkers(pos), exec)
72              app.state = ApplicationState.RUNNING
73            }
74          }
75        }
76      } 
77      // 非spreadOutApps调度方式
78      else {
79        // Pack each app into as few nodes as possible until we've assigned all its cores
80        // 过滤出可用的worker
81        for (worker <- workers if worker.coresFree > 0 && worker.state == WorkerState.ALIVE) {
82          // 获取需要分配core的app
83          for (app <- waitingApps if app.coresLeft > 0) {
84            // 判读app是否可以使用该worker
85            if (canUse(app, worker)) {
86              // 取worker空闲core与app需分配core中的最小值
87              val coresToUse = math.min(worker.coresFree, app.coresLeft)
88              if (coresToUse > 0) {
89                // 根据WorkerInfo和所需的core构建ExecutorDesc
90                val exec = app.addExecutor(worker, coresToUse)
91                // 启动Executor
92                launchExecutor(worker, exec)
93                app.state = ApplicationState.RUNNING
94              }
95            }
96          }
97        }
98      }
99    }

转载于:https://www.cnblogs.com/jianyuan/p/Spark%E7%B3%BB%E5%88%97%E4%B9%8BMaster%E8%B5%84%E6%BA%90%E8%B0%83%E5%BA%A6.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值