Spark技术内幕:究竟什么是RDD

2024-08-27 12:58
文章标签 技术 究竟 spark rdd 内幕

本文主要是介绍Spark技术内幕:究竟什么是RDD,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RDD是Spark最基本,也是最根本的数据抽象。http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf 是关于RDD的论文。如果觉得英文阅读太费时间,可以看这篇译文:http://shiyanjun.cn/archives/744.html 

本文也是基于这篇论文和源码,分析RDD的实现。

第一个问题,RDD是什么?Resilient Distributed Datasets(RDD,) 弹性分布式数据集。RDD是只读的、分区记录的集合。RDD只能基于在稳定物理存储中的数据集和其他已有的RDD上执行确定性操作来创建。这些确定性操作称之为转换,如map、filter、groupBy、join(转换不是程开发人员在RDD上执行的操作)。

RDD不需要物化。RDD含有如何从其他RDD衍生(即计算)出本RDD的相关信息(即Lineage),据此可以从物理存储的数据计算出相应的RDD分区。

看一下内部实现对于RDD的概述:

Internally, each RDD is characterized by five main properties:
 *
 *  - A list of partitions
 *  - A function for computing each split
 *  - A list of dependencies on other RDDs
 *  - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
 *  - Optionally, a list of preferred locations to compute each split on (e.g. block locations for
 *    an HDFS file)

每个RDD有5个主要的属性:

  1. 一组分片(partition),即数据集的基本组成单位
  2. 一个计算每个分片的函数
  3. 对parent RDD的依赖,这个依赖描述了RDD之间的lineage
  4. 对于key-value的RDD,一个Partitioner
  5. 一个列表,存储存取每个partition的preferred位置。对于一个HDFS文件来说,存储每个partition所在的块的位置。

org.apache.spark.rdd.RDD是一个抽象类,定义了RDD的基本操作和属性。这些基本操作包括map,filter和persist。另外,org.apache.spark.rdd.PairRDDFunctions定义了key-value类型的RDD的操作,包括groupByKey,join,reduceByKey,countByKey,saveAsHadoopFile等。org.apache.spark.rdd.SequenceFileRDDFunctions包含了所有的RDD都适用的saveAsSequenceFile。

RDD支持两种操作:转换(transformation从现有的数据集创建一个新的数据集;而动作(actions)在数据集上运行计算后,返回一个值给驱动程序。 例如,map就是一种转换,它将数据集每一个元素都传递给函数,并返回一个新的分布数据集表示结果。另一方面,reduce是一种动作,通过一些函数将所有的元素叠加起来,并将最终结果返回给Driver程序。(不过还有一个并行的reduceByKey,能返回一个分布式数据集)

Spark中的所有转换都是惰性的,也就是说,他们并不会直接计算结果。相反的,它们只是记住应用到基础数据集(例如一个文件)上的这些转换动作。只有当发生一个要求返回结果给Driver的动作时,这些转换才会真正运行。这个设计让Spark更加有效率的运行。例如,我们可以实现:通过map创建的一个新数据集,并在reduce中使用,最终只返回reduce的结果给driver,而不是整个大的新数据集。

默认情况下,每一个转换过的RDD都会在你在它之上执行一个动作时被重新计算。不过,你也可以使用persist(或者cache)方法,持久化一个RDD在内存中。在这种情况下,Spark将会在集群中,保存相关元素,下次你查询这个RDD时,它将能更快速访问。在磁盘上持久化数据集,或在集群间复制数据集也是支持的。

下表列出了Spark中的RDD转换和动作。每个操作都给出了标识,其中方括号表示类型参数。前面说过转换是延迟操作,用于定义新的RDD;而动作启动计算操作,并向用户程序返回值或向外部存储写数据。

表1 Spark中支持的RDD转换和动作
转换 map(f : T ) U) : RDD[T] ) RDD[U]
filter(f : T ) Bool) : RDD[T] ) RDD[T]
flatMap(f : T ) Seq[U]) : RDD[T] ) RDD[U]
sample(fraction : Float) : RDD[T] ) RDD[T] (Deterministic sampling)
groupByKey() : RDD[(K, V)] ) RDD[(K, Seq[V])]
reduceByKey(f : (V; V) ) V) : RDD[(K, V)] ) RDD[(K, V)]
union() : (RDD[T]; RDD[T]) ) RDD[T]
join() : (RDD[(K, V)]; RDD[(K, W)]) ) RDD[(K, (V, W))]
cogroup() : (RDD[(K, V)]; RDD[(K, W)]) ) RDD[(K, (Seq[V], Seq[W]))]
crossProduct() : (RDD[T]; RDD[U]) ) RDD[(T, U)]
mapValues(f : V ) W) : RDD[(K, V)] ) RDD[(K, W)] (Preserves partitioning)
sort(c : Comparator[K]) : RDD[(K, V)] ) RDD[(K, V)]
partitionBy(p : Partitioner[K]) : RDD[(K, V)] ) RDD[(K, V)]
动作 count() : RDD[T] ) Long
collect() : RDD[T] ) Seq[T]
reduce(f : (T; T) ) T) : RDD[T] ) T
lookup(k : K) : RDD[(K, V)] ) Seq[V] (On hash/range partitioned RDDs)
save(path : String) : Outputs RDD to a storage system, e.g., HDFS

注意,有些操作只对键值对可用,比如join。另外,函数名与Scala及其他函数式语言中的API匹配,例如map是一对一的映射,而flatMap是将每个输入映射为一个或多个输出(与MapReduce中的map类似)。

除了这些操作以外,用户还可以请求将RDD缓存起来。而且,用户还可以通过Partitioner类获取RDD的分区顺序,然后将另一个RDD按照同样的方式分区。有些操作会自动产生一个哈希或范围分区的RDD,像groupByKey,reduceByKey和sort等。

从一个例子开始

下面的例子摘自RDD的论文,实现了处理一个HDFS日志文件中错误日志的逻辑。

[java] view plain copy
  1. lines = spark.textFile("hdfs://...")  // lines is a org.apache.spark.rdd.MappedRDD  
  2. errors = lines.filter(_.startsWith("ERROR")) // errors is a org.apache.spark.rdd.FilteredRDD  
  3. errors.cache() // persist 到内存中  
  4. errors.count() // 触发action,计算errors有多少个,即ERROR的多少行  
  5. // Count errors mentioning MySQL:  
  6. errors.filter(_.contains("MySQL")).count()   
  7. // Return the time fields of errors mentioning  
  8. // HDFS as an array (assuming time is field  
  9. // number 3 in a tab-separated format):  
  10. errors.filter(_.contains("HDFS"))  
  11.         .map(_.split('\t')(3))  
  12.         .collect()  


spark是一个org.apache.spark.SparkContext的实例,基本上spark的应用都是以定义一个SparkContext开始的。textFile的定义如下:

[java] view plain copy
  1. /** 
  2.   * Read a text file from HDFS, a local file system (available on all nodes), or any 
  3.   * Hadoop-supported file system URI, and return it as an RDD of Strings. 
  4.   */  
  5.  def textFile(path: String, minPartitions: Int = defaultMinPartitions): RDD[String] = {  
  6.    hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],  
  7.      minPartitions).map(pair => pair._2.toString).setName(path)  
  8.  }  

hadoopFile创建了一个org.apache.spark.rdd.HadoopRDD,而在HadoopRDD上调用map则生成了一个MappedRDD:
[java] view plain copy
  1. /** 
  2.  * Return a new RDD by applying a function to all elements of this RDD. 
  3.  */  
  4. def map[U: ClassTag](f: T => U): RDD[U] = new MappedRDD(this, sc.clean(f))  

errors.cache()并不会立即执行,它的作用是在RDD的计算完成后,将结果cache起来,以供以后的计算使用,这样的话可以加快以后运算的速度。

errors.count() 就触发了一个action,这个时候就需要向集群提交job了:

[java] view plain copy
  1. /** 
  2.   * Return the number of elements in the RDD. 
  3.   */  
  4.  def count(): Long = sc.runJob(this, Utils.getIteratorSize _).sum  


提交后,SparkContext会将runJob提交到DAGScheduler,DAGScheduler会将当前的DAG划分成Stage,然后生成TaskSet后通过TaskScheduler的submitTasks提交tasks,而这又会调用SchedulerBackend,SchedulerBackend会将这些任务发送到Executor去执行。

原文链接:http://blog.csdn.net/anzhsoft/article/details/39851421

这篇关于Spark技术内幕:究竟什么是RDD的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111735

相关文章

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

前端技术(七)——less 教程

一、less简介 1. less是什么? less是一种动态样式语言,属于css预处理器的范畴,它扩展了CSS语言,增加了变量、Mixin、函数等特性,使CSS 更易维护和扩展LESS 既可以在 客户端 上运行 ,也可以借助Node.js在服务端运行。 less的中文官网:https://lesscss.cn/ 2. less编译工具 koala 官网 http://koala-app.

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering)

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering) Power Iteration Clustering (PIC) 是一种基于图的聚类算法,用于在大规模数据集上进行高效的社区检测。PIC 算法的核心思想是通过迭代图的幂运算来发现数据中的潜在簇。该算法适用于处理大规模图数据,特别是在社交网络分析、推荐系统和生物信息学等领域具有广泛应用。Spa

Spring的设计⽬标——《Spring技术内幕》

读《Spring技术内幕》第二版,计文柯著。 如果我们要简要地描述Spring的设计⽬标,可以这么说,Spring为开发者提供的是⼀个⼀站式的轻量级应⽤开发框架(平台)。 作为平台,Spring抽象了我们在 许多应⽤开发中遇到的共性问题;同时,作为⼀个轻量级的应⽤开发框架,Spring和传统的J2EE开发相⽐,有其⾃⾝的特点。 通过这些⾃⾝的特点,Spring充分体现了它的设计理念:在

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的