楔子
源码阅读是一件非常容易的事,也是一件非常难的事。容易的是代码就在那里,一打开就可以看到。难的是要通过代码明白作者当初为什么要这样设计,设计之初要解决的主要问题是什么。
在对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由以下几个主要部分组成
- partitions -- partition集合,一个RDD中有多少data partition
- dependencies -- RDD依赖关系
- compute(parition) -- 对于给定的数据集,需要作哪些计算
- preferredLocations -- 对于data partition的位置偏好
- 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
- 动态view 即 life of a job, 每一个job又分为多个stage,每一个stage中可以包含多个rdd及其transformation,这些stage又是如何映射成为task被distributed到cluster中
参考资料(reference)
- Introduction to Spark Internals http://files.meetup.com/3138542/dev-meetup-dec-2012.pptx
- Resilient Distributed Datasets: A Fault-tolerant Abstraction for In-Memory Cluster Computing https://www.usenix.org/system/files/.../nsdi12-final138.pdf
- Lightning-Fast Cluster Computing with Spark and Shark http://www.meetup.com/TriHUG/events/112474102/
相关推荐
### Apache Spark源码走读之3 -- Task运行期之函数调用关系分析 #### 概述 Apache Spark作为一款高效的大数据处理框架,在其内部有着复杂的任务调度与执行机制。本文将深入探讨Spark中Task执行期间的具体流程以及...
Apache Spark的作业提交与运行机制是其核心组成部分之一,涉及到进程、线程的创建以及任务的调度等多个方面。 首先,要想深入理解Spark作业的提交与运行,需要搭建实验环境。搭建步骤主要包括下载Spark二进制包,...
### Apache Spark源码走读之五:DStream处理的容错性分析 #### 环境搭建与背景 为了深入理解Apache Spark Streaming中DStream处理的容错机制,本文将从一个简单的Spark Streaming示例出发,逐步分析Spark如何确保...
### Apache Spark源码走读之四:DStream实时流数据处理 #### 一、系统概述与流数据特性 本文档探讨了Apache Spark Streaming的核心概念之一——**DStream**(Discretized Stream)及其如何实现对实时流数据的有效...
### Apache Spark源码走读:如何进行代码跟读 #### 概述 本文旨在探讨如何有效地进行Apache Spark源码的阅读与理解。Apache Spark作为一款高性能的分布式计算框架,在大数据处理领域占据着重要地位。其核心由Scala...
### Apache Spark 源码解析概述 #### 一、引言 Apache Spark 是一款开源的大规模数据处理框架,因其高效性、灵活性以及易用性在大数据处理领域得到了广泛的应用。对于想要深入了解Spark内部机制的人来说,阅读其...
Spark作为一个非常优秀的并行处理框架,集成了一些并行化的算法也是理所当然。Graphx是一些图的常用算法在Spark上的并行化实现,同时提供了丰富的API接口。本文就Graphx的代码架构及PageRank在Graphx中的具体实现做...
本文档是关于Storm源码的详细走读笔记,主要分析了Storm的启动场景、Topology提交过程、worker进程中的线程使用情况、消息传递机制以及 TridentTopology的创建和ack机制等多个方面。 首先,文档提到了Storm集群中的...
### C++代码走读意见与开发注意事项 #### 内存管理与安全性 在软件开发过程中,尤其是使用C++这类提供底层内存操作的语言时,代码质量和安全性尤为重要。本篇将基于给定的“C++代码走读意见--开发注意事项”文件中...
IDEA走读Java源码坏境搭建 新建一个普通java项目(如:java8-source) 创建package(tech.sqlclub.java_source)存放java源码 java源码在$JAVA_HOME/src.zip 解压就行,mac用户JAVA_HOME查看如下图: 通过Debug,撸...
### MINA源码走读与实例 #### 一、MINA概述 **MINA**(**M**ulti **I**nterface **N**etwork **A**pplication)是Apache组织下的一款开源网络通信框架,它主要针对TCP/IP、UDP/IP协议栈提供了高效的封装和扩展能力...
《Atheros Minstrel 速率调整算法源码解析》 Minstrel 速率调整算法是 Atheros 无线网卡驱动...通过对源码的阅读和理解,我们可以更深入地掌握无线通信中的速率优化策略,这对于理解和优化无线网络环境具有重要意义。
本文基于博客《【Atheros】Ath9k速率调整算法源码走读》的内容,深入探讨了Atheros Ath9k驱动中的速率调整算法,并与Minstrel算法进行了对比分析。 #### 二、速率控制概述 在Atheros Ath9k驱动中,支持两种速率...
Hadoop,作为开源大数据处理的基石,其核心组件之一就是HDFS(Hadoop Distributed File System),这是一个高度容错性的分布式文件系统,设计用于运行在廉价硬件上,能够处理大规模的数据。HDFS为大数据处理提供了...
《Spark 2.1.1:深度解析与源码阅读笔记》 Spark作为一个开源的分布式计算框架,以其高效、易用和灵活性深受大数据处理领域的欢迎。Spark 2.1.1是其发展中的...希望这份源码阅读笔记能为你的Spark之旅提供有力的支持。
### nova-compute源码分析 #### 一、Nova概述及工作职责 **1.1 Nova的角色与任务** Nova是OpenStack项目中一个至关重要的组成部分,它主要负责虚拟机实例的生命周期管理,包括创建、调度、运行和销毁等功能。具体...
### SPEEDX 代码走读笔记知识点解析 #### LMS算法详解 在文本中提到了LMS(Least Mean Squares)算法的基本公式与参数调整方法。LMS算法是一种用于自适应滤波器的设计方法,主要用于噪声抑制、回声消除等场景。 - ...
1. **申请走读的条件**: - 学生若患有严重影响住校生活的疾病,需提供县级以上医院的诊断证明。 - 因身体缺陷导致生活不能自理的学生可申请。 - 家庭住址距离学校近,交通便利,通勤时间不超过一小时。 - 因...