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

楔子

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

在对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. BST树

    http://www.cnblogs.com/bizhu/archive/2012/08/19/2646328.html 4. 二叉查找树(BST) Technorati 标记: 二叉查找树,BST, ...

  2. mac平台下面ruby环境搭建

    一.安装xcode 先安装 [Xcode](http://developer.apple.com/xcode/) 开发工具,它将帮你安装好 Unix 环境需要的开发包 二.安装 RVM curl -L ...

  3. Java Hour 24 JDBC

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 虽然现在都不会直接写JDBC 了,但是了解毕竟是需要的.当然这个和ADO.Ne ...

  4. JNDI 是什么

    转自:http://blog.csdn.net/zhaosg198312/article/details/3979435 JNDI是 Java 命名与目录接口(Java Naming and Dire ...

  5. Android快捷开关实现(转)

    在Android源码中,提供的快捷开关相对是比较少的,Android4.0系统默认提供的桌面快捷开关AppWidget上只有5种开关(分别是Wifi开关.蓝牙开关.GPS开关.同步开关.亮度设置开关) ...

  6. 开始写github

    公司即将开发手机钱庄网,于是最近在写一些手机上常用的js组件做前期准备. 之所以没有沿用pc的那些插件,原因是: 之前的插件大多数是使用jquery写的 移动端的性能要求更严格 以前写的插件从现在看看 ...

  7. Loadrunner中web_reg_save_param的使用详解

    [摘要]利用实际案例说明如何使用Mercury LoadRunner提取包含在HTML页内的动态信息并创建参数. [关键词]性能测试,压力测试,Mercury LoadRunner 应用范围 在使用L ...

  8. DFS/BFS Codeforces Round #301 (Div. 2) C. Ice Cave

    题目传送门 /* 题意:告诉起点终点,踩一次, '.'变成'X',再踩一次,冰块破碎,问是否能使终点冰破碎 DFS:如题解所说,分三种情况:1. 如果两点重合,只要往外走一步再走回来就行了:2. 若两 ...

  9. 贪心 Gym 100502E Opening Ceremony

    题目传送门 /* 题意:有一堆砖块,每一次操作可以选择消去任意一行,也可以选择消去任意一列.求要消去所有的砖块需要最小的操作数 贪心:首先清楚的是消去最高列的最佳,消去第一行最佳,行列的顺序只对中间过 ...

  10. HDU2196 Computer(树形DP)

    和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...