火花3.0アプリケーションのスケジューリングアルゴリズムの解析

スパークアプリケーションのスケジューリングアルゴリズムのさまざまなバージョンは、まだ違いで、この明確にしています。spark1.3.0から火花1.6.1、spark2.xになりまし最新スパーク3.xでは、いくつかの修正を加えたスケジューリングアルゴリズムへ。ここでは、アプリケーションのスケジューリングメカニズムが火花3.0の最新バージョンを刺激するもの、一緒に勉強します。

DEF startExecutorsOnWorkersプライベート():単位は= { 
//は今のところ、これは我々が最初にフィットアプリケーションにFIFOしようとしておいてくださいAスケジューラ非常に簡単です。
//でザ・キュー、その後のAppザ・SECONDなど
のための(アプリケーション< - waitingApps) {
火花submmitスクリプトは、CPUの各エグゼキュータのコア番号を指定した場合//
//次に、コア数の各執行を割り当て
、各エグゼキュータアサイン用さもなければデフォルト//唯一のコアCPU
ヴァルcoresPerExecutor = app.desc.coresPerExecutor.getOrElse(1)
//コアの場合は、以下の最後の中で、左コアBEが割り当てられてはありませんcoresPerExecutorを残し
コアAPPの必要性の//現在の数が少なく、単一のエグゼキュータ開始番号の割り当てられたCPUコア以上ではない
(場合app.coresLeft> = coresPerExecutor){
//フィルターOUT労働者が持っていないことを起動するための十分なリソースを持っているAN / * *区/ R&LT executo
//状態ALIVE、エグゼキュータを濾過し、さらに作業者を解放
CPUコア下降の残量に応じ//
ヴァルusableWorkers = workers.toArray.filter(_。状態== WorkerState.ALIVE)
.filter(canLaunchExecutor(_、アプリ.desc))
.reverse .sortBy(_。coresFree)
IF(waitingApps.length == && usableWorkers.isEmpty。1){
logWarning(S "$ {} app.idあらゆる労働者の最後以内のApp多くのリソースを必要とはしていたかもしれません。")
}
    // TODO:デフォルトspreadOutAppsスケジューリングアルゴリズムは、アプリケーションが複数のワーカーまでに割り当てられたエグゼキュータのリソースを必要とします
      ヴァルassignedCores = scheduleExecutorsOnWorkers(アプリ、usableWorkers、spreadOutAppsは)

//今、私たちは各ワーカーに割り当てるためにどのように多くのコアを決めたことを、聞かせてのは、それらを割り当てる
ために(POS < - 0 usableWorkers.lengthまでであればassignedCores(POS)> 0){
allocateWorkerResourceToExecutors(
アプリ、assignedCores(POS)、app.desc.coresPerExecutor、usableWorkers(POS))
}
}
}
}
判断一个ワーカー是否可以发布キュータ
DEF canLaunchExecutorプライベート(労働者:WorkerInfo、DESC:ApplicationDescription):ブール= { 
canLaunch(
労働者、
desc.memoryPerExecutorMB、
desc.coresPerExecutor.getOrElse(1)、。
desc.resourceReqsPerExecutor)
}
私たちは、メソッドcanlunchの内部を見てみましょう
DEF canLaunchプライベート(
作業者:WorkerInfo、
memoryReq:INT、
coresReq:INT、
resourceRequirements:配列[ResourceRequirement])
ブール= {
//ワーカー空きメモリ値は、メモリ値が要求されたに等しいより大きい
ヴァルenoughMem = worker.memoryFree> = memoryReqの
コア//番号大きなにワーカーのアイドルの数よりも、または要求されたコアに等しい
ヴァルenoughCores = worker.coresFree> = coresReq
//ワーカー満たす要求されたリソースエグゼキュータ
ヴァルenoughResources = ResourceUtils.resourcesMeetRequirements(
worker.resourcesAmountFree、resourceRequirements)
enoughMem && enoughCores enoughResources &&
}

scheduleExecutorsOnWorkersの先頭へ戻ります
DEF scheduleExecutorsOnWorkersプライベート(
アプリ:にApplicationInfo、
usableWorkers:配列[WorkerInfo]、
spreadOutApps:ブール値):配列[INT] = {
ヴァルcoresPerExecutor = app.desc.coresPerExecutor
ヴァルminCoresPerExecutor coresPerExecutor.getOrElse =(1)
//デフォルトがオンデフォルトの実行者が労働者にのみ開始されているメカニズム、oneExecutorPerWorker
//あなたがcoresPerExecutorを設定した場合、スパーク-submitスクリプトは、十分な時間リソースワーカーで、各ワーカーがオンになり、複数のエグゼキュータを開始
ヴァルを= coresPerExecutor.isEmpty oneExecutorPerWorker
ヴァルmemoryPerExecutor = app.desc.memoryPerExecutorMB
ヴァルresourceReqsPerExecutor app.desc.resourceReqsPerExecutor =
ヴァル= usableWorkers.length numUsable
ヴァルassignedCores =各作業者に与えるために新しい配列[INT](numUsable)コア//数
各ワーカーに新しいエグゼキュータのヴァルassignedExecutors =新しい配列[INT](numUsable)は//番号
VAR coresToAssign = math.min(アプリ。 coresLeft、usableWorkers.map(_。coresFree).SUM)

ワーカー//ノードが執行を開始するかどうかを決定
するブール= {(:のInt POS)DEF canLaunchExecutorForApp

ヴァルkeepScheduling = coresToAssign> = minCoresPerExecutor
assignedCores(POS)> = minCoresPerExecutor -ヴァルenoughCores = usableWorkers(POS).coresFree
ヴァルassignedExecutorNum = assignedExecutors(POS )

// WEは、複数のワーカーあたりのエグゼキュータは、WE CAN常に起動し新しい新しいエグゼキュータ。場合は許可し
、既にON ANエグゼキュータは、この労働者がある場合に//がそうでなければ、ただのIT以上のコアを与える。

// coresPerExecutorで火花-submitスクリプトセットした場合値、
//現在の作業員は、まだこのアプリケーション執行のために割り当てられていない
!ヴァルlaunchingNewExecutor = oneExecutorPerWorker assignedExecutorNum == 0 ||
// TODO:新しいエグゼキュータを開始することができます
(launchingNewExecutor){もし
ヴァルassignedMemory = assignedExecutorNum * memoryPerExecutor
assignedMemory> = memoryPerExecutor -ヴァルenoughMemory = usableWorkers(POS).memoryFree
ヴァルassignedResources = resourceReqsPerExecutor.map {
REQ => req.resourceName - > req.amount * assignedExecutorNum
} .toMap
ヴァルresourcesFree = usableWorkers(POS).resourcesAmountFree.map {
場合(RNAME、フリー)=> RNAME - >(フリー- assignedResources.getOrElse(RNAME、0))
}
ヴァルenoughResources = ResourceUtils.resourcesMeetRequirements(
resourcesFree、resourceReqsPerExecutor)
ヴァルunderLimit = assignedExecutors。合計+ app.executors.size <app.executorLimit
keepScheduling && && enoughCores enoughMemory && && enoughResources underLimit
}他{
//私たちは、既存のエグゼキュータにコアを追加している必要はありませんので
、//チェックするためのメモリとエグゼキュータの制限
// TODO:不满足启动新的執行条件、则在老的Executorの上追加コア数
keepScheduling && enoughCores
}
}

//これ以上の労働者が何らかの対応しないことができるまでのエグゼキュータを起動してください
。//より多くの執行を、または私たちは、このアプリケーションの制限に達している場合

のvar freeWorkers =(0 numUsableまで).filter(canLaunchExecutorForApp)
しばらく(freeWorkers.nonEmpty){
freeWorkers.foreach {POS =>
VAR keepScheduling =真
一方、(keepScheduling && canLaunchExecutorForApp(POS)){
coresToAssign - = minCoresPerExecutor
assignedCores(POS)+ = minCoresPerExecutor

//起動WEがエグゼキュータ労働者ごとに1つ、その後毎週1反復ザ割り当てコアである場合。
そうでない場合に//ザ執行、各反復ザ割り当てコア。 。新しい新規エグゼキュータ
IF(oneExecutorPerWorker){
// TODO:ワーカーノードは、新たな執行、minCoresPerExecutor古いエグゼキュータ(この場合のデフォルト値1)に割り当てられたCPUコアを開始できない場合
assignedExecutors(POS)を1 =。
} {他
// TODO:ワーカーノードは、新たな執行のCPUコアを割り当てる新しいエグゼキュータ、minCoresPerExecutor(値その時点でcoresPerExecutorスクリプトを火花送信構成されている)を開始することができる場合
assignedExecutors(POS)+ 1 =。
}

//としてのエグゼキュー広がっOUT OUT ANファイル印加手段広がる
可能性のある労働者のAS //多くは、そうでない場合は、OUTを広めているWE、WEは、維持する必要があり
、ITSすべてのリソースのこの労働者の使用まで//スケジューリングエグゼキュータON WE。
//そうでない場合だけで次の作業員への移動中。
IF(spreadOutApps){
// TODO:ここにkeepScheduling =偽の着信は、労働者にのみ、すべてのコア一度割り当てられ、その後、作業員まで、コア割り当てられた次の作業員に進む
// TODO:完全トラバーサル
偽=にkeepScheduling
}
}
}
freeWorkers = freeWorkers.filter(canLaunchExecutorForApp)
}
//戻り各ワーカーノード番号割り当てられたCPUコア
assignedCores
}

さんはallocateWorkerResourceToExecutorsを分析してみましょう
プライベートデフallocateWorkerResourceToExecutors(
アプリ:にApplicationInfo、
assignedCores:INT、
coresPerExecutor:オプション[INT]、
作業者:WorkerInfo):単位= {
//実行部あたりのコアの数を指定した場合、我々は、割り当てられたコア分割
均等この作業者に//をない残りエグゼキュータのうち。
//そうでなければ、私たちは、この労働者のすべてのassignedCoresをつかみ、単一のエグゼキュータを起動します。
ヴァルnumExecutors = coresPerExecutor.map {assignedCores / _} .getOrElse(1)
バルcoresToAssign = coresPerExecutor.getOrElse(assignedCores)
(I < - numExecutors 1)のために{
valを割り当て= worker.acquireResources(app.desc.resourceReqsPerExecutor)
// TODO:さらにこのアプリケーション今回キュータ
ヴァルエグゼクティブ= app.addExecutor(ワーカー、coresToAssign、割り当て)
// TODO:launchExecutorの送信コマンドワーカースレッドに
launchExecutor(ワーカー、EXEC)
app.state = ApplicationState.RUNNING
}
}
OK、この時点で、スパーク火花3.0アプリケーションのスケジューリングアルゴリズム分析の最新バージョンは完了です!

おすすめ

転載: www.cnblogs.com/guodong1789/p/11976774.html