欢迎转载,转载请注明出处,徽沪一郎。

楔子

源码阅读是一件非常容易的事,也是一件非常难的事。容易的是代码就在那里,一打开就可以看到。难的是要通过代码明白作者当初为什么要这样设计,设计之初要解决的主要问题是什么。

在对Spark的源码进行具体的走读之前,如果想要快速对Spark的有一个整体性的认识,阅读Matei Zaharia做的Spark论文是一个非常不错的选择。

在阅读该论文的基础之上,再结合Spark作者在2012 Developer Meetup上做的演讲Introduction to Spark Internals,那么对于Spark的内部实现会有一个比较大概的了解。

有了上述的两篇文章奠定基础之后,再来进行源码阅读,那么就会知道分析的重点及难点。

基本概念(Basic Concepts)

RDD - resillient distributed dataset 弹性分布式数据集

Operation - 作用于RDD的各种操作分为transformation和action

Job - 作业,一个JOB包含多个RDD及作用于相应RDD上的各种operation

Stage - 一个作业分为多个阶段

Partition - 数据分区, 一个RDD中的数据可以分成多个不同的区

DAG - Directed Acycle graph, 有向无环图,反应RDD之间的依赖关系

Narrow dependency - 窄依赖,子RDD依赖于父RDD中固定的data partition

Wide Dependency - 宽依赖,子RDD对父RDD中的所有data partition都有依赖

Caching Managenment -- 缓存管理,对RDD的中间计算结果进行缓存管理以加快整体的处理速度

编程模型(Programming Model)

RDD是只读的数据分区集合,注意是数据集

作用于RDD上的Operation分为transformantion和action。 经Transformation处理之后,数据集中的内容会发生更改,由数据集A转换成为数据集B;而经Action处理之后,数据集中的内容会被归约为一个具体的数值。

只有当RDD上有action时,该RDD及其父RDD上的所有operation才会被提交到cluster中真正的被执行。

从代码到动态运行,涉及到的组件如下图所示。

演示代码


val sc = new SparkContext("Spark://...", "MyJob", home, jars)
val file = sc.textFile("hdfs://...")
val errors = file.filter(_.contains("ERROR"))
errors.cache()
errors.count()

运行态(Runtime view)

不管什么样的静态模型,其在动态运行的时候无外乎由进程,线程组成。

用Spark的术语来说,static view称为dataset view,而dynamic view称为parition view. 关系如图所示

在Spark中的task可以对应于线程,worker是一个个的进程,worker由driver来进行管理。

那么问题来了,这一个个的task是如何从RDD演变过来的呢?下节将详细回答这个问题。

部署(Deployment view)

当有Action作用于某RDD时,该action会作为一个job被提交。

在提交的过程中,DAGScheduler模块介入运算,计算RDD之间的依赖关系。RDD之间的依赖关系就形成了DAG。

每一个JOB被分为多个stage,划分stage的一个主要依据是当前计算因子的输入是否是确定的,如果是则将其分在同一个stage,避免多个stage之间的消息传递开销。

当stage被提交之后,由taskscheduler来根据stage来计算所需要的task,并将task提交到对应的worker.

Spark支持以下几种部署模式1)standalone 2)Mesos 3) yarn. 这些部署模式将作为taskscheduler的初始化入参。

RDD接口(RDD Interface)

RDD由以下几个主要部分组成

  1. partitions --    partition集合,一个RDD中有多少data partition
  2. dependencies -- RDD依赖关系
  3. compute(parition) -- 对于给定的数据集,需要作哪些计算
  4. preferredLocations --  对于data partition的位置偏好
  5. partitioner -- 对于计算出来的数据结果如何分发

缓存机制(caching)

RDD的中间计算结果可以被缓存起来,缓存先选Memory,如果Memory不够的话,将会被写入到磁盘中。

根据LRU(last-recent update)来决定哪先内容继续保存在内存,哪些保存到磁盘。

容错性(Fault-tolerant)

从最初始的RDD到衍生出来的最后一个RDD,中间要经过一系列的处理。那么如何处理中间环节出现错误的场景呢?

Spark提供的解决方案是只对失效的data partition进行事件重演,而无须对整个数据全集进行事件重演,这样可以大大加快场景恢复的开销。

RDD又是如何知道自己的data partition的number该是多少?如果是hdfs文件,那么hdfs文件的block将会成为一个重要的计算依据。

集群管理(cluster management)

task运行在cluster之上,除了spark自身提供的standalone部署模式之外,spark还内在支持yarn和mesos.

Yarn来负责计算资源的调度和监控,根据监控结果来重启失效的task或者是重新distributed task一旦有新的node加入cluster的话。

这一部分的内容需要参考yarn的文档。

小结

在源码阅读时,需要重点把握以下两大主线。

  • 静态view 即 RDD, transformation and action
  • 动态viewlife of a job, 每一个job又分为多个stage,每一个stage中可以包含多个rdd及其transformation,这些stage又是如何映射成为task被distributed到cluster中

参考资料(reference)

  1. Introduction to Spark Internals http://files.meetup.com/3138542/dev-meetup-dec-2012.pptx
  2. Resilient Distributed Datasets: A Fault-tolerant Abstraction for In-Memory Cluster Computing  https://www.usenix.org/system/files/.../nsdi12-final138.pdf
  3. Lightning-Fast Cluster Computing with Spark and Shark   http://www.meetup.com/TriHUG/events/112474102/

Apache Spark源码走读之1 -- Spark论文阅读笔记的更多相关文章

  1. Apache Spark源码走读之16 -- spark repl实现详解

    欢迎转载,转载请注明出处,徽沪一郎. 概要 之所以对spark shell的内部实现产生兴趣全部缘于好奇代码的编译加载过程,scala是需要编译才能执行的语言,但提供的scala repl可以实现代码 ...

  2. Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读. 拟牛顿法 数学原理 代码实现 L-BFGS算法中使 ...

  3. Apache Spark源码走读之9 -- Spark源码编译

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本来源码编译没有什么可说的,对于java项目来说,只要会点maven或ant的简单命令,依葫芦画瓢,一下子就ok了.但到了Spark上面,事情似乎不这么简单 ...

  4. Apache Spark源码走读之8 -- Spark on Yarn

    欢迎转载,转载请注明出处,徽沪一郎. 概要 Hadoop2中的Yarn是一个分布式计算资源的管理平台,由于其有极好的模型抽象,非常有可能成为分布式计算资源管理的事实标准.其主要职责将是分布式计算集群的 ...

  5. Apache Spark源码走读之7 -- Standalone部署方式分析

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 在Spark源码走读系列之2中曾经提到Spark能以Standalone的方式来运行cluster,但没有对Application的提交与具体运行流程做详细 ...

  6. spark 源码分析之十--Spark RPC剖析之TransportResponseHandler、TransportRequestHandler和TransportChannelHandler剖析

    spark 源码分析之十--Spark RPC剖析之TransportResponseHandler.TransportRequestHandler和TransportChannelHandler剖析 ...

  7. spark 源码分析之十一--Spark RPC剖析之TransportClient、TransportServer剖析

    TransportClient类说明 先来看,官方文档给出的说明: Client for fetching consecutive chunks of a pre-negotiated stream. ...

  8. Apache Spark源码走读之13 -- hiveql on spark实现详解

    欢迎转载,转载请注明出处,徽沪一郎 概要 在新近发布的spark 1.0中新加了sql的模块,更为引人注意的是对hive中的hiveql也提供了良好的支持,作为一个源码分析控,了解一下spark是如何 ...

  9. Apache Spark源码走读之18 -- 使用Intellij idea调试Spark源码

    欢迎转载,转载请注明出处,徽沪一郎. 概要 上篇博文讲述了如何通过修改源码来查看调用堆栈,尽管也很实用,但每修改一次都需要编译,花费的时间不少,效率不高,而且属于侵入性的修改,不优雅.本篇讲述如何使用 ...

随机推荐

  1. 解决Tomcat 6.0 只支持 J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules

    通过search,发现在project的.setting folder下面,有个名为org.eclipse.wst.common.project.facet.core.xml的文件,里面配置有各种版本 ...

  2. 越狱后想禁用Spotlight

    如果你的是ios7越狱后不想用Spotlight搜索功能,大老板源的NoSpot ios7可轻松帮你实现.亲测可用……………………

  3. myeclipse中的js文件报错

    方法一:myeclipse9 很特殊 和 myeclipse10 不一样,所以myeclipse9 不能使用该方法. 方法二: 为了做一个页面特效,导入了一个jquery文件,怎想,myeclipse ...

  4. Android Studio安装与配置

    谷歌已经停止支持eclipse开发android了,转向android studio是大势所趋,笔者由于电脑配置的原因, 以前迟迟不愿意向android studio,现如今因为开始学习materia ...

  5. CI中REST URL含有中文怎么处理(报错:The URI you submitted has disallowed characters)

    解决方法: 客户端在发送GET URL请求的时候,将含有中文的URL编码即可 比如: 原始:http://localhost/qk/rest/user_album_api/get_user_album ...

  6. poj 2186 有向图强连通分量

    奶牛互相之间有爱慕关系,找到被其它奶牛都喜欢的奶牛的数目 用tarjan缩点,然后判断有向图中出度为0的联通分量的个数,如果为1就输出联通分量中的点的数目,否则输出0. 算法源自kb模板 #inclu ...

  7. JAVA学习:maven开发环境快速搭建

    转自:http://tech.it168.com/a2011/1204/1283/000001283307.shtml 最近,开发中要用到maven,所以对maven进行了简单的学习.因为有个mave ...

  8. 【codevs2822】爱在心中 tarjan 缩点+理解

    [codevs2822]爱在心中 2014年1月26日5580 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸, ...

  9. js:语言精髓笔记6----作用域

    js基础语法:由语句.表达式和变量构成:   语句是主要表达方式:单语句->复合语句(代码块)->程序片段(函数):js中没有单元和程序的概念: 作用域: 语法作用域与变量作用域的区别:前 ...

  10. ural 1283. Dwarf

    1283. Dwarf Time limit: 1.0 secondMemory limit: 64 MB Venus dwarfs are rather unpleasant creatures: ...