容错指的是一个系统在部分模块出现故障时还能否持续的对外提供服务,一个高可用(HA)的系统应该具有很高的容错性,系统不会因为一点小的错误导致系统性能严重下降或者造成系统瘫痪。
对于一个大的集群系统来说,机器故障、网络异常等都是很常见的,其不能因为这些原因造成集群系统不能提供服务。所以像Spark这样的大型分布式计算集群提供了很多的容错机制来提高整个系统的可用性,Spark的容错机制可以通过Executor、Worker和Master的异常处理来体现,下面分别对它们进行介绍。
在Spark中,Executor的作用是:负责执行任务的运行,并把任务运行状态发给Driver。下面以独立运行模式分析Executor出现异常的情况。Executor异常容错过程图如下:
其中虚线为正常运行的通信线路,实线为异常处理步骤。
流程如下:
(1)首先看Executor的启动过程
在集群中由Master给应用程序分配运行资源后,然后在Worker中启动 ExecutorRunner ,而 ExecutorRunner根据当前的运行模式启动CoarseGrainedExecutorBackend进程,当该进程会向 Driver 发送注册Executor信息。如果注册成功,则CoarseGraineaExecutorBackend在其内部启动Executor。Executor由 ExecutorRunner进行管理,当Executor出现异常时(如所运行容器CoarseGrainedExecutorBackend进程异常退出等),由 ExecutorRunner 捕获该异常并发送 ExecutorStateChanged消息给Worker。
(2) Worker 接收到ExecutorStateChanged消息
在Worker的 handleExecutorStateChanged方法中,根据Executor 状态进行信息更新,同时把 Executor状态信息转发给Master。
(3)Master 接收到 Executor状态变化消息
如果发现Executor 出现异常退出,则调用Master. schedule方法,尝试获取可用的 Worker 节点并启动Executor,而这个Worker很可能不是失败之前运行Executor 的 Worker 节点。该尝试系统会进行10次,如果超过10次,则标记该应用运行失败并移除集群中移除该应用。这种限定失败次数是为了避免提交的应用程序存在Bug而反复提交,进而挤占集群宝贵的资源。
以独立运行模式来讨论Worker异常。Spark的 独立运行模式采用的是Master/Slave的结构,其中Slave是由Worker来担任的其在运行的时候会发送心跳给Master,让 Master 知道Worker 的实时状态。另一方面Master也会检测注册的Worker是否连接超时,因为在集群运行过程中,可能由于机器宕机或者进程被杀死等原因造成Worker进程异常退出。Worker异常容错过程图如下:
(1)Master接收Worker的心疼来监测其实时状态,同时,Master中的onStart方法中也有检测Worker超时的线程。实现代码如下:
case Heartbeat(workerId, worker) =>
idToWorker.get(workerId) match {
case Some(workerInfo) =>
workerInfo.lastHeartbeat = System.currentTimeMillis()
case None =>
if (workers.map(_.id).contains(workerId)) {
logWarning(s"Got heartbeat from unregistered worker $workerId." +
" Asking it to re-register.")
worker.send(ReconnectWorker(masterUrl))
} else {
logWarning(s"Got heartbeat from unregistered worker $workerId." +
" This worker was never registered, so ignoring the heartbeat.")
}
}
override def onStart(): Unit = {
…
checkForWorkerTimeOutTask = forwardMessageThread.scheduleAtFixedRate(new Runnable {
override def run(): Unit = Utils.tryLogNonFatalError {
self.send(CheckForWorkerTimeOut)
}
}, 0, WORKER_TIMEOUT_MS, TimeUnit.MILLISECONDS)
…
}
(2)当Worker出现超时时,Master调用timeOutDeadWorkers方法进行处理。代码实现如下:
/** Check for, and remove, any timed-out workers */
private def timeOutDeadWorkers() {
// Copy the workers into an array so we don’t modify the hashset while iterating through it
val currentTime = System.currentTimeMillis()
val toRemove = workers.filter(_.lastHeartbeat < currentTime - WORKER_TIMEOUT_MS).toArray
for (worker <- toRemove) {
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!