[spark源码剖析]RDD相关源码阅读笔记

spark源码阅读二-spark application运行过程 本篇文章主要讲述一个application的运行过程。 大体分为三部分:(1)SparkConf创建;(2)SparkContext创建;(3)任务执行。 阅读详情

RDD相关源码阅读笔记

转载请标明出处:http://blog.youkuaiyun.com/bigbigdata/article/details/48412199

最好的源码阅读方法就是调试,没有之一

之前其实有阅读过RDD相关的源码,最近学习过程中发现在之前原本阅读过的模块中有一些『关节』并没有打通,所以想通过调试的方式来更细致得学习源码。
本文为编写测试用例并调试RDD相关模块的笔记,并没有列出具体的调试过程,仅列出结论以做备忘,特别是那些比较容易忽略或者说是其他blog或者书本中比较少提到的。

RDD重要成员及方法

依赖

RDD共提供了3个与依赖相关的成员,如下:

//< 保存与其直接父RDDs的依赖
private var dependencies_ : Seq[Dependency[_]] = null

protected def getDependencies: Seq[Dependency[_]] = deps

final def dependencies: Seq[Dependency[_]] = {
    checkpointRDD.map(r => List(new OneToOneDependency(r))).getOrElse {
      if (dependencies_ == null) {
        dependencies_ = getDependencies
      }
      dependencies_
    }
}

当调试代码时,若碰到明明由其他RDD执行transform操作而生成的RDD的dependencies_成员为空,比如下面这种情况:
这里写图片描述
莫要惊慌,并不是hashRdd1没有依赖的父RDD,而是没有将该依赖赋值给dependencies_而已,在产生hashRdd1后,只需调用hashRdd1.dependencies就可以在调试的监控窗口看到hashRdd1.dependencies_该有的值了。

这并没有什么不妥,在之后DAGScheduler划分Stage过程中,会调用所有RDD的dependencies方法。

分区

RDD中与分区相关的成员有:

protected def getPartitions: Array[Partition]

//< partitions_为数组类型
@transient private var partitions_ : Array[Partition] = null

final def partitions: Array[Partition] = {
    checkpointRDD.map(_.partitions).getOrElse {
      if (partitions_ == null) {
        partitions_ = getPartitions
      }
      partitions_
    }
}

//< 可选的
@transient val partitioner: Option[Partitioner] = None

分区相关的需要知道以下几点:
1. 与『依赖』一样,若明明由其他RDD执行transform操作而生成的RDD的partitions_成员为空并不是该RDD没有分区,只是还没将分区赋值给partitions_,之后的操作会通过调用成员函数partitions进行赋值并返回
2. partitioner为可选值,对于非key-value的RDD该值为None。key-value类型的RDD也需要在创建时指定partitioner。目前公有HashPartitioner,RangePartitioner两种Partitioner

缓存等级

RDD支持缓存,可支持缓存到磁盘、内存、OffHeap及是否序列化缓存。RDD包含缓存等级成员:

private var storageLevel: StorageLevel = StorageLevel.NONE,默认为StorageLevel.NONE,StorageLevel定义及StorageLevel.NONE定义如下:

    //< StorageLevel定义
    class StorageLevel private(
        private var _useDisk: Boolean,
        private var _useMemory: Boolean,
        private var _useOffHeap: Boolean,
        private var _deserialized: Boolean,
        private var _replication: Int = 1){...}

    object StorageLevel {
    val NONE = new StorageLevel(false, false, false, false)
    ...
    }

从上面代码可以看出默认值StorageLevel.NONE表示不以任何方式缓存RDD

CreationSite

对于这个成员,我不知道怎么用中文描述好,该成员在RDD主构造函数中定义如下

@transient private[spark] val creationSite = sc.getCallSite(),表示程序员写的具体哪个类中的哪行代码生成这个RDD。

有两种格式,一种是shortForm,即短格式,如parallelize at DivedeStage.scala:14;还有一种是longForm,即长格式,如

org.apache.spark.SparkContext.parallelize(SparkContext.scala:563)
DivideStages$.main(DivedeStage.scala:14)
DivideStages.main(DivedeStage.scala)

RDD还提供了getCreationSite方法以获取该creationSite,该方法会在RDD.toString方法中被调用以告知该RDD是程序员写的哪行代码生成的

checkpoint相关

在执行rdd的checkpoint之前,首先要调用SparkContext.setCheckpointDir(directory: String)来设置checkpoint的目录,其实这里设置的checkpoint目录还不是最终checkpoint目录,SparkContext.setCheckpointDir实现会在参数指定的目录下新建一个以UUID.randomUUID().toString命名的目录,如果application跑在集群环境下,该目录必须是个HDFS目录。

在RDD调用checkpoint方法时,如下:

def checkpoint() {
  if (context.checkpointDir.isEmpty) {
    throw new SparkException("Checkpoint directory has not been set in the SparkContext")
  } else if (checkpointData.isEmpty) {
    checkpointData = Some(new RDDCheckpointData(this))
    checkpointData.get.markForCheckpoint()
  }
}

会创建一个RDDCheckpointData实例,该类保存与checkpint相关的所有信息,包括:关联的RDD,check point状态(公有Initialized, MarkedForCheckpoint, CheckpointingInProgress, Checkpointed集中状态),check point文件及check point得到的RDD。

在调用checkpointData = Some(new RDDCheckpointData(this))时,check point状态被置为Initialized。之后调用checkpointData.get.markForCheckpoint()将check point状态置为MarkedForCheckpoint。这里只是标记该RDD需要check point,并不会真的执行check point。

check point是个比较复杂的流程,我将会专门写一篇文章介绍,这里就不展开了。

others

RDD的成员和方法有好几十个,无法一一列举。最后再列几个方法:


  //< 由子类实现来计算一个给定的分区
  @DeveloperApi
  def compute(split: Partition, context: TaskContext): Iterator[T]


  //< 获得某个partition的优先位置,这对调度task非常重要
  protected def getPreferredLocations(split: Partition): Seq[String] = Nil

  //< 缓存RDD,可以缓存内存、磁盘、OffHeap等;cache方法其实也是对该方法进行了封装
  def persist(newLevel: StorageLevel): this.type = {
    ...
  }

小知识点

  1. RDD具有name属性,可通过RDD.setName设置,name默认为null
  2. RDD id如何确定?
    答:任何类型的RDD都继承于abstract class RDD,那么,在创建任何类型RDD实例时,都会调用该abstract class RDD的主构造函数,在该abstract class RDD主构造函数中通过调用val id: Int = sc.newRddId()获取RDD id,sc对应的application中每生成一个RDD,sc.newRddId()就会被调用一次并返回比上次大1的值,从0开始。从这里也可以看出,application中所有rdd的id都是由SparkContext分配的,越先生成的rdd的id越小

扩展阅读

Spark配置实验报告 一、Spark与Scala版本兼容问题: Spark运行在Java 8 +,Python 2.7 + / 3.4 +和R 3.1+上。对于Scala API,Spark 2.4.2使用Scala 2.12。您需要使用兼容的Scala版本(2.12.x)。 请注意,自Spark 2.2.0起,对2.6.5之前的Java 7,Python 2.6和旧Hadoop版本的支持已被删除。自2.3.0起,对S... 阅读详情

相关推荐

Ubuntu22.04安装ROS1

代表使用 2 线程进行编译,可以根据 CPU 适当调整。如果出现小乌龟窗口,说明安装成功 🎉!启动成功,则打开另一个终端,测试。需要解决一些兼容性问题,因为。由于 Ubuntu 22.04。过程,确保成功安装。

asafriend的博客 4646

2万字硬核spark源码精讲手册

spark源码精讲,结合企业级开发和面试实战重点关注内容

5092

雷电模拟器+Python 3.11:手把手教你用Frida-dexdump给安卓APK脱壳(附GDA查壳)

本文详细介绍了如何使用雷电模拟器和Python 3.11配合Frida-dexdump工具进行安卓APK脱壳的全流程。从环境配置、工具安装到脱壳操作和问题排查,提供了包含30+关键截图的保姆级教程,适合零基础用户快速上手。重点讲解了Frida工具链的使用技巧和GDA查壳方法,帮助读者掌握移动应用安全分析的基础技能。

weixin_42568801的博客 327

Spark源码

spark源码

m0_67991849的博客 1366

MST-GAT: Enhancing Anomaly Detection in Multimodal Time Series with Intra- and Inter-Modal Attention

本文深入解析了MST-GAT模型,这是一种通过模态内与模态间注意力机制增强多模态时间序列异常检测的新方法。它通过构建图结构显式建模传感器间的复杂时空依赖,并结合时间卷积网络与联合优化策略,有效降低了传统方法中常见的误报与漏报问题,在工业监控等场景中展现出卓越性能。

weixin_29079671的博客 150

【STM32学习】(29)STM32实现595驱动三个数码管(标准库和HAL库实现)

我选用的单片机型号为:STM32F103系列 74LS595是一个串转并行输出的芯片,它能为单片机节省很多的IO口,应用场景广泛。 现要求三个数码管动态显示,常规设计都是并行实现,需要8个IO数据口,然后还需要3个IO片选数码管接口,这样大大占用了IO口,导致连接的外设变少。因此我们引入74LS595芯片。电路设计如下: 只需要三个共阴极数码管与三个595芯片级联即可完成,通过RCLK,SCK,SER三个IO即可完成对数码管的动态控制并显示。电路焊接的实物图如下: 要求完成功能:实现数.

XiaoCaiDaYong的博客 8264

【读懂面经中的源码】SPARK源码解析——Spark任务提交、调度、执行过程

【读懂面经中的源码】SPARK源码解析——Spark任务提交、调度、执行过程。这是读源码的博客,主要从面经出发,深入理解Spark任务提交、调度、执行过程,期间通过源码加深理解面经中提到的原理。文章包括三部分,分别是面筋部分、Spark任务提交、SparkContext初始化、Executor启动、Task启动的部分。文章三部分的讲解将有助于读者同学理解Spark任务提交、调度、执行详细原理,希望能够帮助到各位读者同学!!!

番茄薯仔 1126

立创EDA开源足轮机器人:基于STM32F407与ESP32的LQR自平衡与FOC驱动设计全解析

本文详细解析了基于立创EDA平台的开源足轮机器人项目。该项目采用STM32F407作为主控,ESP32负责无线通信,并应用LQR自平衡算法与FOC驱动技术,实现了机器人的稳定站立、移动转向及复杂地形适应能力。文章深入剖析了其硬件架构、软件设计及调试经验,为机器人运动控制学习提供了宝贵参考。

weixin_42608299的博客 232

spark源码 spark on yarn环境的创建

ApplicationMaster.sparkContextInitialized(sc) --当前的初始化环境已经完成了,让ApplicationMaster 中的val sc = ThreadUtils.awaitResult 继续往下执行。driver线程执行的过程中,注册应用程序是阻塞的,当反射执行main方法的时候,去创建SparkContext并完成初始化之后,通知注册应用程序继续执行,当executor反向注册之后,然后通知action算子继续执行。

weixin_43015677的博客 688

Frida Stalker实战:如何用指令级追踪破解OLLVM混淆的AES算法

本文深入探讨了如何使用Frida Stalker进行指令级追踪,破解经过OLLVM混淆的AES算法。通过动态分析技术,逆向工程师可以精准识别控制流平坦化等混淆手段,还原算法逻辑,特别适用于移动安全领域的加密算法分析。文章提供了详细的配置指南、核心机制解析和实战案例,帮助读者掌握对抗高级代码混淆的有效方法。

weixin_29325955的博客 475

【WRF-Chem工具】pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

WW、forever的博客 210

Spark 3.0.0集群启动原理和源码详解

 本课程讲解Spark 3.0.0 集群启动原理和源码详解的内容,包括:Master 启动原理和源码详解: Master 启动的原理详解、 Master 启动的源码详解、 Master HA 双机切换、 Master 的注册机制和状态管理解密; Worker 启动原理和源码详解: Worker 启动的原理流程、 Worker 启动的源码详解; ExecutorBackend 启动原理和源码详解: ExecutorBackend 接口与Executor 的关系、 ExecutorBackend 的不同实现、ExecutorBackend 中的通信、 ExecutorBackend 的异常处理; Executor 中任务的执行: Executor 中任务的加载、Executor 中的任务线程池、 任务执行失败处理、 揭秘TaskRunner; Executor 执行结果的处理方式。           

基于STM32设计的水质检测系统_333

水质安全对生态环境、农业生产、工业制造以及人类健康至关重要。针对传统水质检测方式检测周期长、成本高、实时性差的问题,本项目设计并实现了一种基于STM32的水质检测系统。系统采用STM32F103RCT6作为主控芯片,集成水温、pH值、电导率和浊度等传感器,能够实时采集水质数据,并通过OLED显示屏进行本地显示。同时,利用Air724UG 4G模块通过MQTT协议将数据上传至华为云IoT平台,实现远程监测。用户可通过Qt5开发的Android手机APP和Windows上位机查看水质数据,并接收超限报警提示。此

713

spark core源码阅读-RDD详细介绍(四)

之前对RDD有一个大体概念了解,这一节我们需要深入了解它,了解在源码中到底是什么, 怎么产生的,给个rdd之间怎么依赖的,最后又怎么生成spark job 我们还是先从一个例子下手: val sc = new SparkContext(sparkConf) val res = sc .textFile(args(0)) .flatMap(line =&gt; line.spli...

吃货先生的博客 4970

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Spark SQL内核剖析(一)

在这一节简单介绍了Spark涉及到的几个简单技术,包括RDD编程模型、DataFrame和DataSet用户接口。 简单介绍了Spark SQL内部机制中设计的基本概念。 Spark SQL 内部实现上述流程中平台无关部分的基础框架叫做Catalyst,其中涉及的几种数据结构和概念如下。 在Spark SQL 内部实现中,InternalRow就是用来表示一行行数据的类,物理算子树所产生的RDD即为RDD[InternalRow],包含numFields和update方法,以及各列数据对应的get和set方

vic_torsun的博客 1646

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spark2源码阅读——内存分配

Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色。理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优。本文旨在梳理出 Spark 内存管理的脉络,抛砖引玉,引出读者对这个话题的深入探讨。本文中阐述的原理基于 Spark 2.1 版本,阅读本文需要读者有一定的 Spark 和 Java 基础,了解 RDD、Shuff...

liangwqi的博客 247

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Spark MLlib统计学习算法:假设检验与相关性分析源码解读

Spark MLlib是Spark生态系统中用于机器学习的核心库,提供了丰富的统计学习算法实现。本文将深入剖析其中假设检验与相关性分析的底层原理及源码实现,帮助开发者理解如何利用这些工具进行数据探索和特征选择。 ## 一、假设检验:从理论到Spark实现 ### 1.1 假设检验的核心概念 假设检验是统计推断的重要方法,用于判断样本数据是否支持某个统计假设。Spark MLlib主要实现了两

gitblog_00857的博客 676

Spark

Spark与Scala版本兼容问题: Spark运行在Java 8 +,Python 2.7 + / 3.4 +和R 3.1+上。对于Scala API,Spark 2.4.2使用Scala 2.12。您需要使用兼容的Scala版本(2.12.x)。 请注意,自Spark 2.2.0起,对2.6.5之前的Java 7,Python 2.6和旧Hadoop版本的支持已被删除。自2.3.0起,对Sca...

weixin_44722987的博客 285

Hadoop_Spark数据一致性难题:原理剖析与实战解决方案

随着企业数字化转型的深入,大数据系统需同时支撑离线批处理(如Hadoop)、实时流计算(如Spark Streaming)、交互式查询(如Spark SQL)等多元场景。数据一致性作为系统可靠性的核心指标,直接影响业务决策的准确性(如金融风控、用户画像)。HDFS的“一次写入多次读取”模型的一致性边界HBase的多版本并发控制(MVCC)实现Spark RDD的血统(Lineage)容错机制的一致性局限Spark SQL与数据湖(Delta Lake)的ACID事务实践。

Agentic AI人工智能与大数据正在引领一场新智能科技革命。 891

[Apache Spark源码阅读]天堂之门——SparkContext解析

稍微了解Spark源码的人应该都知道SparkContext,作为整个Project的程序入口,其重要性不言而喻,许多大牛也在源码分析的文章中对其做了很多相关的深入分析和解读。这里,结合自己前段时间的阅读体会,与大家共同讨论学习一下Spark的入口对象—天堂之门—SparkContex。 SparkContex位于项目的源码路径\spark-master\core\src\main\s...

diegua5958的博客 204

spark-3.0.1源码阅读之文件数据计算

spark-3.0.1源码阅读之文件数据计算1 调试1.1 makeRDD方法1.2 saveAsTextFile方法1.3 collect方法2 关于executor的最大并行度的说明3 总结   Spark作为分布式的计算引擎,本身并不存储要计算的数据源,需要使用外部的数据,所以这些外部数据接入spark的方式也不同.在接入数据后,spark使用自身的一套计算模式,对数据进行计算,并输出到目标目录中. 1 调试   使用core子工程下的测试类FileSuite,使用第一个test("text fil

qq_33570700的博客 315

【亲测免费】 Spark源码解析:深入理解大数据处理的艺术

Spark源码解析:深入理解大数据处理的艺术 在大数据领域,Apache Spark 是一个不可或缺的名字,它以其高效、易用和强大的并行计算能力赢得了广泛赞誉。为了帮助开发者更深入地理解和利用Spark,我们今天要推荐的是一个名为 "" 的开源项目,该项目由 weibin0516 创建,旨在深度解析 Spark 源代码,提供实践指导。 项目简介 spark-sourcecode...

gitblog_00026的博客 584

眨眼 Spark 都 3.0 了!

福利手慢无廖雪峰的大数据开发必备教程-Spark视频资料终于免费了!限额领取~今年不少人觉得职场晋升不那么顺畅,说是大环境所致,这也没错。但身边有些人,却能在如此“艰难”的环境下,顺利...

程序员吴师兄的博客 266

Spark修炼之道(高级篇)——Spark源码阅读:第三节 Spark Job的提交

前一我们分析了SparkContext的创建,这一节,我们介绍在RDD执行的时候,如何提交job进行分析,同样是下面的源码: import org.apache.spark.{SparkConf, SparkContext} object SparkWordCount{ def main(args: Array[String])...

weixin_34149796的博客 200

大数据相关资料论文小结

前言 不知不觉,2020年已经过去一半了,最近突然反应过来自己也看了不少文献资料了,就想着把看过的文献和觉得比较好的书籍做一个总结,基本都是大数据分布式领域的,回顾自己学识的同时,也给想从事或这个领域的小伙伴一些参考 ????。最后顺便把接下来要看的东西列个列表,也会将自己学习的心得和经验分享出来,有需要的童鞋可以参考参考。 另外有些文献看完我会进行整理和输出,这部分链接我一并附在文献的介绍后面,后面看的书或是文献也会保持这种习惯,如果觉得有兴趣欢迎各位大佬交流,顺便也可以点波关注~~ 论文总结 MapRe

zzzzMing -大数据/数据分析/数据挖掘 2577
上一篇: [Spark源码剖析] Task的调度与执行源码剖析
下一篇: 协同过滤
bigbigdata
博客等级 码龄11年 5粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值