一、Spark RDD容错原理

  RDD不同的依赖关系导致Spark对不同的依赖关系有不同的处理方式。

  对于宽依赖而言,由于宽依赖实质是指父RDD的一个分区会对应一个子RDD的多个分区,在此情况下出现部分计算结果丢失,单一计算丢失的数据无法达到效果,便采用重新计算该步骤中的所有数据,从而会导致计算数据重复;对于窄依赖而言,由于窄依赖实质是指父RDD的分区最多被一个子RDD使用,在此情况下出现部分计算的错误,由于计算结果的数据只与依赖的父RDD的相关数据有关,所以不需要重新计算所有数据,只重新计算出错部分的数据即可。

二、RDD容错的四大核心要点

  Spark框架层面的容错机制,主要分为三大层面(调度层、RDD血统层、Checkpoint层),在这三大层面中包括Spark RDD容错四大核心要点。

  (1)Stage输出失败,上层调度器DAGScheduler重试。
  (2)Spark计算中,Task内部任务失败,底层调度器重试。
  (3)RDD Lineage血统中窄依赖、宽依赖计算。
  (4)Checkpoint缓存。

1.调度层(包含DAG生成和Task重算两大核心)

  从调度层面讲,错误主要出现在两个方面,分别是在Stage输出时出错和在计算时出错。

  1)DAG生成层

  Stage输出失败,上层调度器DAGScheduler会进行重试,DAGScheduler.scala的resubmitFailedStages的源码如下。

  /**
* Resubmit any failed stages. Ordinarily called after a small amount of time has passed since
* the last fetch failure.
*/
private[scheduler] def resubmitFailedStages() {
// 判断是否存在失败的Stages
if (failedStages.size > 0) {
// Failed stages may be removed by job cancellation, so failed might be empty even if
// the ResubmitFailedStages event has been scheduled.
// 失败的阶段可以通过作业取消删除,如果ResubmitFailedStages事件已调度,失败将是空值
logInfo("Resubmitting failed stages")
clearCacheLocs()
// 获取所有失败Stage的列表
val failedStagesCopy = failedStages.toArray
// 清空failedStages
failedStages.clear()
// 对之前获取所有失败的Stage,根据jobId排序后逐一重试
for (stage <- failedStagesCopy.sortBy(_.firstJobId)) {
submitStage(stage)
}
}
submitWaitingStages()
}

  2)Task计算层

  Spark计算过程中,计算内部某个Task任务出现失败,底层调度器会对此Task进行若干次重试(默认4次)。TaskSetManager.scala的handleFailedTask的源码如下。

/**
* Marks the task as failed, re-adds it to the list of pending tasks, and notifies the
* DAG Scheduler.
*/
def handleFailedTask(tid: Long, state: TaskState, reason: TaskEndReason) { ...... if (!isZombie && state != TaskState.KILLED
&& reason.isInstanceOf[TaskFailedReason]
&& reason.asInstanceOf[TaskFailedReason].countTowardsTaskFailures) {
assert (null != failureReason)
// 对失败的Task的numFailures进行计数加1
numFailures(index) += 1
// 判断失败的Task计数是否大于设定的最大失败次数,如果大于,则输出日志,并不再重试
if (numFailures(index) >= maxTaskFailures) {
logError("Task %d in stage %s failed %d times; aborting job".format(
index, taskSet.id, maxTaskFailures))
abort("Task %d in stage %s failed %d times, most recent failure: %s\nDriver stacktrace:"
.format(index, taskSet.id, maxTaskFailures, failureReason), failureException)
return
}
}
// 如果运行的Task为0时,则完成Task步骤
maybeFinishTaskSet()
}

2.RDD Lineage血统层容错

  Spark中RDD采用高度受限的分布式共享内存,且新的RDD的产生只能够通过其他RDD上的批量操作来创建,依赖于以RDD的Lineage为核心的容错处理,在迭代计算方面比Hadoop快20多倍,同时还可以在5~7s内交互式地查询TB级别的数据集。

  Spark RDD实现基于Lineage的容错机制,基于RDD的各项transformation构成了compute chain,在部分计算结果丢失的时候可以根据Lineage重新恢复计算。

  (1)在窄依赖中,在子RDD的分区丢失,要重算父RDD分区时,父RDD相应分区的所有数据都是子RDD分区的数据,并不存在冗余计算。
  (2)在宽依赖情况下,丢失一个子RDD分区,重算的每个父RDD的每个分区的所有数据并不是都给丢失的子RDD分区用的,会有一部分数据相当于对应的是未丢失的子RDD分区中需要的数据,这样就会产生冗余计算开销和巨大的性能浪费。

3.checkpoint层容错

  Spark checkpoint通过将RDD写入Disk作检查点,是Spark lineage容错的辅助,lineage过长会造成容错成本过高,这时在中间阶段做检查点容错,如果之后有节点出现问题而丢失分区,从做检查点的RDD开始重做Lineage,就会减少开销。

  checkpoint主要适用于以下两种情况:

  (1)DAG中的Lineage过长,如果重算,开销太大,如PageRank、ALS等。
  (2)尤其适合在宽依赖上作checkpoint,这个时候就可以避免为Lineage重新计算而带来的冗余计算。

 

Spark之RDD容错原理及四大核心要点的更多相关文章

  1. Javaweb学习笔记——(十七)——————JDBC的原理、四大核心类、四大参数、预编译、Dao模式、批处理、大数据、时间类型的转换

    JDBC入门 *导入jar包:驱动 *加载驱动类:Class.forName("类名"); *给出url.username.password,其中url背下来 *使用DriverM ...

  2. spark RDD底层原理

    RDD底层实现原理 RDD是一个分布式数据集,顾名思义,其数据应该分部存储于多台机器上.事实上,每个RDD的数据都以Block的形式存储于多台机器上,下图是Spark的RDD存储架构图,其中每个Exe ...

  3. Spark的RDD原理以及2.0特性的介绍

    转载自:http://www.tuicool.com/articles/7VNfyif 王联辉,曾在腾讯,Intel 等公司从事大数据相关的工作.2013 年 - 2016 年先后负责腾讯 Yarn ...

  4. Spark Streaming简介及原理

    简介: SparkStreaming是一套框架. SparkStreaming是Spark核心API的一个扩展,可以实现高吞吐量的,具备容错机制的实时流数据处理. 支持多种数据源获取数据: Spark ...

  5. Spark之RDD的定义及五大特性

    RDD是分布式内存的一个抽象概念,是一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,能横跨集群所有节点并行计算,是一种基于工作集的应用抽象. RDD底层存储原理:其数据分布存储于多台机器上 ...

  6. Spark 中 RDD的运行机制

    1. RDD 的设计与运行原理 Spark 的核心是建立在统一的抽象 RDD 之上,基于 RDD 的转换和行动操作使得 Spark 的各个组件可以无缝进行集成,从而在同一个应用程序中完成大数据计算任务 ...

  7. 49、Spark Streaming基本工作原理

    一.大数据实时计算介绍 1.概述 Spark Streaming,其实就是一种Spark提供的,对于大数据,进行实时计算的一种框架.它的底层,其实,也是基于我们之前讲解的Spark Core的. 基本 ...

  8. spark shuffle:分区原理及相关的疑问

    一.分区原理 1.为什么要分区?(这个借用别人的一段话来阐述.) 为了减少网络传输,需要增加cpu计算负载.数据分区,在分布式集群里,网络通信的代价很大,减少网络传输可以极大提升性能.mapreduc ...

  9. [Spark] Spark的RDD编程

    本篇博客中的操作都在 ./bin/pyspark 中执行. RDD,即弹性分布式数据集(Resilient Distributed Dataset),是Spark对数据的核心抽象.RDD是分布式元素的 ...

随机推荐

  1. 【题解】洛谷 P1080 国王游戏

    目录 题目 思路 \(Code\) 题目 P1080 国王游戏 思路 贪心+高精度.按\(a \times b\)从小到大排序就可以了. \(Code\) #include<bits/stdc+ ...

  2. 面试官问线程安全的List,看完再也不怕了!

    最近在Java技术栈知识星球里面有球友问到了线程安全的 List: 扫码查看答案或加入知识星球 栈长在之前的文章<出场率比较高的一道多线程安全面试题>里面讲过 ArrayList 的不安全 ...

  3. Python并发请求之requests_future模块使用

    # -*- coding: utf-8 -*- # @Time : 2019-12-09 10:00 # @Author : cxa # @File : demo.py # @Software: Py ...

  4. [技术博客] 数据库1+N查询问题

    目录 问题简述 问题解决 group的方法简化查询 改正后的代码 作者:庄廓然 问题简述 本次开发过程中我们用到了rails的orm框架,使用orm框架可以很方便地进行对象的关联和查询,例如查询一个用 ...

  5. Gamma阶段第二次scrum meeting

    每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...

  6. 线程:Java中wait、notify、notifyAll使用详解

    基础知识 首先我们需要知道,这几个都是Object对象的方法.换言之,Java中所有的对象都有这些方法. public final native void notify(); public final ...

  7. C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案

    C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案 新建Console控制台项目项目,然后添加Team和Person 这2个类,如下: Team和P ...

  8. Java地址:

    GitHub:https://github.com/nanchen2251 个人博客:https://nanchen2251.github.io/ 简书地址:http://www.jianshu.co ...

  9. window操作系统分区

    注意GPT分区模式不能创建扩展分区和逻辑分区

  10. Python logging模块日志存储位置踩坑

    问题描述 项目过程中写了一个小模块,设计到了日志存储的问题,结果发现了个小问题. 代码结构如下: db.py run.py 其中db.py是操作数据库抽象出来的一个类,run.py是业务逻辑代码.两个 ...