Spark学习笔记:Spark算子及应用

目录

Spark算子及应用

1.RDD基础

什么是RDD?

创建RDD

使用RDD的算子(函数、方法)对数据进行计算

2.常见的算子以及示例

常用的Transformation算子

常用的Action算子

         RDD算子示例

5.RDD的缓存机制

通过实例进行测试

6.RDD的Checkpoint(检查点)机制:容错机制

本地目录

HDFS目录

7.RDD的依赖关系和Stage的划分依据


Spark算子及应用

1.RDD基础

RDD(Resilient Distributed DataSet),弹性分布式数据集,是Spark中最基本,也是最重要的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD具有数据流模型的特点:自动容错、位置感知度调度和可伸缩性。RDD允许用户在执行多个查询时显式地将工作集缓存在内存中,后续的查询能重用工作集,这极大地提升了查询速度。因为有RDD,所以Spark才支持分布式的计算。RDD由分区组成。

什么是RDD?

通过查看Spark的源码,可以获取到RDD的一些描述,在org.apache.spark.RDD中可以看到

稍微翻译了一下

弹性分布式数据集(RDD), Spark中的基本抽象。代表一个不可变的,可以并行操作的元素的分区集合。
这个类包含RDD上的所有基本操作,如“map”、“filter”和“persist”。
此外,[org.apache.spark.rdd.PairRDDFunctions]包含的操作只能在key-value形式的RDDs上可用,如'groupByKey'和'join';
[org.apache.spark.rdd.DoubleRDDFunctions]包含的操作只能在Double类型RDD上可用
[org.apache.spark.rdd.SequenceFileRDDFunctions]包含的操作用于保存为SequenceFiles的RDD
所有的操作在任何类型正确的RDD(例如RDD[(Int, Int)])上都是隐式自动可用的。

在内部,每个RDD有五个主要特性:
  - 分区列表,即RDD由分区组成
  - 一个对每个split(数据分区)进行计算的函数,也称为RDD的算子
  - RDD之间存在依赖关系
  - 可选,key-value类型RDD的partitioner,用来对RDD的数据做手动分区(例如,哈希分区)
  - 可选,计算每个split的首选位置列表(例如,一个HDFS文件的块地址)
Spark中的所有调度和执行都基于这些方法,允许每个RDD实现自己的计算方式。
实际上,用户可以通过重写这些函数实现定制的RDD(例如,从一个新的存储系统中读取数据)
请参考http://people.csail.mit.edu/matei/papers/2012/nsdi_spark.pdf获取有关RDD内部的详细信息。

这里用一张示意图来说明,什么是RDD

创建RDD

(1)通过sc的parallelize的方法进行创建

(2)直接读取外部数据源来创建RDD

使用RDD的算子(函数、方法)对数据进行计算

 

2.常见的算子以及示例

RDD的算子有两种类型
(1)Transformation:不会触发计算,延时加载(计算)
(2)Action:直接触发计算

常用的Transformation算子

map(func):对原来的RDD的每个元素,进行func运算,返回一个新的RDD,比如WordCount里的map((_,1))
filter:过滤,选择满足条件的元素
flatMap:等同于Scala的flatMap
mapPartitions(func):对原来的RDD中的每个分区进行运算,并返回一个新的RDD
mapPartitionsWithIndex(func):对原来的RDD中的每个分区进行运算,并返回一个新的RDD,与mapPartitions(func)区别在于,这个算子返回的RDD带有下标
union:并集
intersecttion:交集
distinct:去重
groupByKey:分组
reduceByKey:分组,跟groupByKey的区别在于,reduceByKey会有一个本地操作(相当于MapReduce中的Combiner),因此效率会比groupByKey效率更高一些

常用的Action算子

collect():触发计算
count:求RDD中的元素个数
first:求RDD中的第一个元素
take(n):取RDD数据集合中的前n个元素
saveAsTextFile:将RDD以文本文件的形式存储到文件系统中
foreach(func):对RDD中每个元素进行func操作,但没有返回值

RDD算子示例

(1)创建一个数值类型的RDD

(2)对每个元素乘以2,并且排序

(3)过滤掉小于50的数字

(4)创建一个字符串类型的RDD

(5)对这个RDD根据空格来做split,不过首先要压平集合

(6)集合运算
先定义两个List

并集

交集

(7)分组操作

5.RDD的缓存机制

RDD通过persist方法或cache方法可以将前面的计算结果缓存,但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,并供后面重用。

在Spark的源码中可以看到,其实cache也是调用了无参的persist,而persist里面有一个很重要的参数就是StorageLevel

那StorageLevel又是什么呢,还是从源码里找答案


从类StorageLevel的成员变量名上我们可以看出每个变量值的含义,是否使用磁盘,内存,堆外内存,反序列化,备份因子,然后在它的伴生对象上可以看见使用构造方法构造的不同参数搭配所对应的缓存级别,这些参数名是用来在persist方法里指定的。

而且从apply方法中可以看到,这里是实现了单例模式的饿汉式。

通过实例进行测试

向HDFS中导入测试数据,大概是30M的大小

在Spark shell中读入文件,并进行文件行的计数,然后我们对数据进行缓存后再执行计算,注意,这里执行了count之后才会触发计算,将数据缓存下来,当再次执行count的时候,就会用到缓存的结果


在Spark的Web界面上可以看到效率,接近10倍的效率提升

6.RDD的Checkpoint(检查点)机制:容错机制

(1)检查点是辅助RDD的lineage(血统)进行容错的管理。
任务后面的步骤依赖于前面的步骤,如果一旦出现错误,则无法往后继续计算,就必须从头开始,这样必然会使得效率降低。整个计算的周期就叫lineage,lineage越长,出错的概率越大。所以我们可以设置一个检查点,如果后面的计算过程出错,则不需要从头重新进行计算,则可以从检查点的地方再次开始计算。

(2)RDD的检查点有两种类型:本地目录(即检查点的信息保存在本地的文件夹,一般用于开发和测试),HDFS目录(保存在HDFS,多用于生产环境)

本地目录

需要把spark-shell运行在本地模式上
sc.setCheckpointDir("/root/temp/sparkcheckpoint")

HDFS目录

需要把spark-shell运行在集群模式上
sc.setCheckpointDir("hdfs://centos:9000/sparkcheckpoint")

7.RDD的依赖关系和Stage的划分依据

RDD和它依赖的父RDD的关系有两种不通的类型,宽依赖和窄依赖
宽依赖是指父RDD的每个分区都可能被多个子RDD分区所使用,子RDD分区通常对应所有的父RDD分区。

窄依赖是指父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应常数个父RDD分区。

没有依赖关系的stage是可以并行执行的,DAG根据宽依赖来划分stage,每个宽依赖的处理均会是一个stage的划分点。同一个stage中的多个操作会在一个task中完成。因为子RDD的分区仅依赖于父RDD的一个分区,因此这些步骤可以串行执行。

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值