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日志文件里错误日志的逻辑。

lines = spark.textFile("hdfs://...")  // lines is a org.apache.spark.rdd.MappedRDD
errors = lines.filter(_.startsWith("ERROR")) // errors is a org.apache.spark.rdd.FilteredRDD
errors.cache() // persist 到内存中
errors.count() // 触发action。计算errors有多少个,即ERROR的多少行
// Count errors mentioning MySQL:
errors.filter(_.contains("MySQL")).count()
// Return the time fields of errors mentioning
// HDFS as an array (assuming time is field
// number 3 in a tab-separated format):
errors.filter(_.contains("HDFS"))
.map(_.split('\t')(3))
.collect()

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

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

hadoopFile创建了一个org.apache.spark.rdd.HadoopRDD,而在HadoopRDD上调用map则生成了一个MappedRDD:

  /**
* Return a new RDD by applying a function to all elements of this RDD.
*/
def map[U: ClassTag](f: T => U): RDD[U] = new MappedRDD(this, sc.clean(f))

errors.cache()并不会马上运行,它的作用是在RDD的计算完毕后,将结果cache起来。以供以后的计算使用。这种话能够加快以后运算的速度。

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

 /**
* Return the number of elements in the RDD.
*/
def count(): Long = sc.runJob(this, Utils.getIteratorSize _).sum

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

怎样划分Stage?怎样生成tasks?接下来将得到解决。

为了明天还要上班,,早在今天休息吧。

版权声明:本文博主原创文章,博客,未经同意不得转载。

Spark里边:到底是什么RDD的更多相关文章

  1. Spark菜鸟学习营Day3 RDD编程进阶

    Spark菜鸟学习营Day3 RDD编程进阶 RDD代码简化 对于昨天练习的代码,我们可以从几个方面来简化: 使用fluent风格写法,可以减少对于中间变量的定义. 使用lambda表示式来替换对象写 ...

  2. Spark Streaming揭秘 Day18 空RDD判断及程序中止机制

    Spark Streaming揭秘 Day18 空RDD判断及程序中止机制 空RDD的处理 从API我们可以知道在SparkStreaming中,对于RDD的操作一般都是在foreachRDD和Tra ...

  3. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  4. 【Spark 深入学习 07】RDD编程之旅基础篇03-键值对RDD

    --------------------- 本节内容: · 键值对RDD出现背景 · 键值对RDD转化操作实例 · 键值对RDD行动操作实例 · 键值对RDD数据分区 · 参考资料 --------- ...

  5. Hive数据分析——Spark是一种基于rdd(弹性数据集)的内存分布式并行处理框架,比于Hadoop将大量的中间结果写入HDFS,Spark避免了中间结果的持久化

    转自:http://blog.csdn.net/wh_springer/article/details/51842496 近十年来,随着Hadoop生态系统的不断完善,Hadoop早已成为大数据事实上 ...

  6. 且谈 Apache Spark 的 API 三剑客:RDD、DataFrame 和 Dataset

    作者:Jules S. Damji 译者:足下 本文翻译自 A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets ,翻译已 ...

  7. Learning Spark中文版--第三章--RDD编程(1)

       本章介绍了Spark用于数据处理的核心抽象概念,具有弹性的分布式数据集(RDD).一个RDD仅仅是一个分布式的元素集合.在Spark中,所有工作都表示为创建新的RDDs.转换现有的RDD,或者调 ...

  8. Learning Spark中文版--第三章--RDD编程(2)

    Common Transformations and Actions   本章中,我们浏览了Spark中大多数常见的transformation(转换)和action(开工).在包含特定数据类型的RD ...

  9. Spark学习(一)--RDD操作

    标签(空格分隔): 学习笔记 Spark编程模型的两种抽象:RDD(Resilient Distributed Dataset)和两种共享变量(支持并行计算的广播变量和累加器). RDD RDD是一种 ...

随机推荐

  1. uva 11396Claw Decomposotion(二分图判定)

     题目大意:给出一个简单无向图,每一个点的度为3.推断是否能将此图分解成若干爪的形式.使得每条边都仅仅出如今唯一的爪中. (点能够多次出如今爪中) 这道题实质上就是问这个图是否为二分图,dfs判定 ...

  2. .Net程序猿乐Android发展---(1)环境结构

    对于没有接触Android人才发展,你可能会觉得Android更难以发展.接下来的一段时间,我们将了解Android开发的详细细节,主要是面对.NET程序猿,来看看.NET程序猿如何进行Android ...

  3. [转载] 树莓派读取温湿度传感器DHT11

    原文地址: http://blog.csdn.net/liang890319/article/details/8739683 硬件: 树莓派 2.0 DHT模块  接树莓派5V GND GPIO1 功 ...

  4. 判断闰年(go语言版本)

    import "strconv" func IsLeapYear(y string) bool { //y == 2000, 2004 //判断是否为闰年 year, _ := s ...

  5. 重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口

    原文:重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口 [源码下载] 重新想象 Windows 8 Store Apps (26) ...

  6. ueditor文本编辑器的使用

    1,头部引用 <link href="ueditor/themes/default/css/ueditor.css" rel="stylesheet" t ...

  7. redmine使用汇总redmine软件工程过程

    1.强制性当一个新的问题:轨道.议题.叙述性说明.状态.优先.分配给.父任务(假设没有可以不填,假设有请务必填写).开始日期.预计时间.党羽,请注意,这时候一定不要填写完成时间 2.如果你想在实时登记 ...

  8. 【Web探索之旅】第三部分第二课:IP地址和域名

    内容简介 1.第三部分第二课:IP地址和域名 2.第三部分第三课预告:协议 第三部分第二课:IP地址和域名 上一课我们说了在Web之中,全球各地有无数台机器,有些充当客户机,有些作为服务器. 那么这些 ...

  9. ViewData ViewBag ViewModel

    ViewBag 里可以携带dynamic的数据. Model 是从control传过来的模型数据. 我自己感觉ViewBag 可以携带少量的数据,但是我同事喜欢部分页partial 请求,ViewBa ...

  10. 在AcGIS随着大数据的生成DEM

    在ArcGIS产生DEM时间.数据来源是经常有的高程点.轮廓线,该高程点.等高线密集,可能有几千万.甚至亿高程点.轮廓线. 如果您使用这些矢量数据生成TIN.不能实现的,由于生成TIN时,支持的最大结 ...