Spark技術內幕:Worker源碼與架構解析

來源:互聯網
上載者:User

標籤:spark

首先通過一張Spark的架構圖來瞭解Worker在Spark中的作用和地位:


Worker所起的作用有以下幾個:

1. 接受Master的指令,啟動或者殺掉Executor

2. 接受Master的指令,啟動或者殺掉Driver

3. 報告Executor/Driver的狀態到Master

4. 心跳到Master,心跳逾時則Master認為Worker已經掛了不能工作了

5. 向GUI報告Worker的狀態


說白了,Worker就是整個叢集真正幹活的。首先看一下Worker重要的資料結構:

  val executors = new HashMap[String, ExecutorRunner]  val finishedExecutors = new HashMap[String, ExecutorRunner]  val drivers = new HashMap[String, DriverRunner]  val finishedDrivers = new HashMap[String, DriverRunner]

這些Hash Map儲存了名字和實體時間的對應關係,方便通過名字直接找到實體進行調用。

看一下如何啟動Executor:

case LaunchExecutor(masterUrl, appId, execId, appDesc, cores_, memory_) =>      if (masterUrl != activeMasterUrl) {        logWarning("Invalid Master (" + masterUrl + ") attempted to launch executor.")      } else {        try {          logInfo("Asked to launch executor %s/%d for %s".format(appId, execId, appDesc.name))          val manager = new ExecutorRunner(appId, execId, appDesc, cores_, memory_,            self, workerId, host,            appDesc.sparkHome.map(userSparkHome => new File(userSparkHome)).getOrElse(sparkHome),            workDir, akkaUrl, ExecutorState.RUNNING)          executors(appId + "/" + execId) = manager          manager.start()          coresUsed += cores_          memoryUsed += memory_          masterLock.synchronized {            master ! ExecutorStateChanged(appId, execId, manager.state, None, None)          }        } catch {          case e: Exception => {            logError("Failed to launch executor %s/%d for %s".format(appId, execId, appDesc.name))            if (executors.contains(appId + "/" + execId)) {              executors(appId + "/" + execId).kill()              executors -= appId + "/" + execId            }            masterLock.synchronized {              master ! ExecutorStateChanged(appId, execId, ExecutorState.FAILED, None, None)            }          }        }


1行到3行是驗證該命令是否發自一個合法的Master。7到10行定義了一個ExecutorRunner,實際上系統並沒有一個類叫做Executor,我們所說的Executor實際上是由ExecutorRunner實現的,這個名字起得也比較貼切。11行將建立的executor放到上面提到的Hash Map中。然後12行啟動這個Executor。13行和14行將現在已經使用的core和memory進行的統計。15到17行實際上是向Master報告Executor的狀態。這裡需要加鎖。

如果在這過程中有異常拋出,那麼需要check是否是executor已經加到Hash Map中,如果有則首先停止它,然後從Hash Map中刪除它。並且向Master report Executor是FAILED的。Master會重新啟動新的Executor。


接下來看一下Driver的Hash Map的使用,通過KillDriver:

    case KillDriver(driverId) => {      logInfo(s"Asked to kill driver $driverId")      drivers.get(driverId) match {        case Some(runner) =>          runner.kill()        case None =>          logError(s"Asked to kill unknown driver $driverId")      }    }

這個KillDirver的命令實際上由Master發出的,而Master實際上接收了Client的kill driver的命令。這個也可以看出Scala語言的簡潔性。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.