Spark--怎样理解RDD

打印 上一主题 下一主题

主题 1836|帖子 1836|积分 5508

1、概念

  rdd是对数据集的逻辑体现,自己并不存储数据,只是封装了计算逻辑,并构建实行计划,通过保存血缘关系来记录rdd的实行过程和历史(当一个rdd须要重算时,系统会根据血缘关系追溯到最初的数据源,重建丢失的数据),调用行动算子时,会从数据源读取数据并举行计算。
2、五大属性

(1)compute计算函数

形貌本RDD的数据怎样被计算出来,本质上是运算逻辑的迭代器。
(2)依赖RDD列表

一个或多个前序RDD。
(3)分区列表

RDD被分成多个分区。
(4)(k, v)类型rdd的分区器



  • 普通RDD:没有分区器,分区数在创建和Transformation时决定,后续可以通过repartition或coalesce修改。
  • PairRDD:具有分区器的概念,可以基于键分区,常用于须要快速聚合的场景。
(5)每个分区的首选计算实行位置

  为了提高计算服从,会根据数据当地化级别,将任务分配到离数据最近的计算节点举行计算。
3、本质

  rdd的本质是迭代器。
  迭代器是一种用于访问聚集元素的计划模式,允许我们按需逐个访问聚会合的元素,而无需一次性加载整个聚集,允许一次仅访问一个元素,访问后可以进步到下一个元素,但无法返回上一个元素。
  RDD在调用行动算子(如collect,count,reduce等)时,每个Task中会创建个独立的迭代器。
   实行具体过程:
(1)分区:当使用RDD时,数据被分成多个分区,每个分区可以独立处理惩罚。
(2)任务调理:当行动算子被调用时,spark会为每个分区创建一个任务(Task)。
(3)创建迭代器:在每个Task开始实行时,Spark会为该分区的RDD创建一个迭代器,从而能够逐个访问该分区的数据。
(4)逐个处理惩罚:迭代器以惰性方式逐一处理惩罚元素,实行你所定义的操纵;比方,映射、过滤、聚合等。
(5)结果汇总:在全部分区的Task完成后,Spark将结果汇总,并返回给驱动程序。
    并行处理惩罚的优点:
(1)内存服从:每个Task只在内存中处理惩罚当前迭代器的数据,制止了同时加载整个RDD所需的数据。
(2)并行处理惩罚:每个Task可以在不同的Executor上并行实行,加快计速度。
(3)故障恢复:由于RDD的分区和迭代器的特性,Spark可以轻松地重算丢失的分区数据。
4、特点

(1)不可变性

一旦创建,rdd的内容就不能被修改了,可以通过转化操纵创建一个新的rdd。
(2)弹性

可以在任务失败或数据丢失时,自动重算。
(3)支持分布计算

可以在整个集群中分布式地举行计算,支持大规模数据的处理惩罚。
5、RDD,DataFrame与DataSet的区别与联系

(1)RDD与DataFrame的区别

  RDD中的数据没有布局信息,是一种基础的数据布局,重要使用函数式编程风格。
  DataFrame是在RDD的基础上加上了一层schema,类似于表格的数据布局,有列名和数据类型的信息,提供了更加简洁的代码书写方式,支持SQL查询。

  上图直观地体现了DataFrame和RDD的区别。左侧的RDD[Person]固然以Person为类型参数,但Spark框架自己不了解Person类的内部布局。而右侧的DataFrame却提供了具体的布局信息,使得Spark SQL可以清楚地知道该数据会合包罗哪些列,每列的名称和类型各是什么。DataFrame多了数据的布局信息,即schema。RDD是分布式的Java对象的聚集。DataFrame是分布式的Row对象的聚集。DataFrame除了提供了比RDD更丰富的算子以外,更重要的特点是提升实行服从、淘汰数据读取以及实行计划的优化,比如filter下推、裁剪等。
RDD:
  1. val rdd = sc.parallelize(Seq(1, 2, 3, 4, 5))
  2. val result = rdd.map(_ * 2).collect()
复制代码
DataFrame:
  1. val df = spark.read.json("path/to/json")
  2. val result = df.filter($"age" > 20).select("name", "age")
复制代码
(2)DataFrame与DataSet的区别
DataFrame 可以看作是 DataSet[Row],其中 Row 是一个通用的行类型。DataFrame可以以为是Dataset的一个特例,重要区别是DataSet每一个record存储的是一个强类型值而不是一个Row。
DataSet:
  1. case class Person(name: String, age: Int)
  2. val ds = spark.read.json("path/to/json").as[Person]
  3. val result = ds.filter(_.age > 20).map(_.name)
复制代码
6、宽RDD和窄RDD的概念

RDD在计算过程中,会被划分成多个Stage,这依靠的就是RDD之间的依赖关系。RDD有2种依赖关系(宽依赖和窄依赖),根据不同的依赖关系来确定是否须要shuffle,根据是否须要shuffle来确定是否须要划分stage。
(1)窄依赖(NarrowDependency)有如下两种:

① OneToOneDependency
父RDD的分区与子RDD的分区是一一对应的关系。
② RangeDependency
父RDD与子RDD是多对一的关系,但是父RDD的分区与子RDD的分区是一对一的关系,所以分区之间并不会交织,每个子RDD依然对应父RDD的一个分区。

窄RDD分区间的计算是一对一的,每个子RDD只须要读取父RDD的一个分区即可举行计算,所以不须要shuffle,即不须要划分stage。
2、宽依赖:

ShuffleDependency

ShuffleDependency中,每个子RDD的每个分区,都要拿到父RDD的每个分区的数据,才气举行计算。正因云云,在碰到宽依赖时,须要对数据举行shuffle处理惩罚,划分stage。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表