Spark---持久化,共享变量和RDD之间的依赖关系详解

一、持久化

1、什么是持久化,为什么要持久化

Spark中最重要的功能之一是跨操作在内存中持久化(或缓存)数据集。当您持久化RDD时,每个节点将其计算的任何分区存储在内存中,并在该数据集(或从该数据集派生的数据集)上的其他操作中重用这些分区。这使得未来的行动更快(通常超过10倍)。缓存是迭代算法和快速交互使用的关键工具。

2、如何进行持久化

持久化的方法就是rdd.persist()或者rdd.cache()

3、持久化策略

可以通过persist(StoreageLevle的对象)来指定持久化策略

scala 复制代码
rdd.persist(StorageLevel.MEMORY_ONLY)
持久化策略 含义
MEMORY_ONLY(默认) rdd中的数据,以未经序列化的java对象格式,存储在内存中。如果内存不足,剩余的部分不持久化,使用的时候,没有持久化的那一部分数据重新加载。这种效率是最高,但是是对内存要求最高的。
MEMORY_ONLY_SER 就比MEMORY_ONLY多了一个SER序列化,保存在内存中的数据是经过序列化之后的字节数组,同时每一个partition此时就是一个比较大的字节数组。
MEMORY_AND_DISK 和MEMORY_ONLY相比就多了一个,内存存不下的数据存储在磁盘中
MEMEORY_AND_DISK_SER 比MEMORY_AND_DISK多了个序列化
DISK_ONLY 就是MEMORY_ONLY对应,都保存在磁盘,效率太差,一般不用。
xxx_2 就是上述多个策略后面加了一个_2,比如MEMORY_ONLY_2,MEMORY_AND_DISK_SER_2等等,就多了一个replicate而已,备份,所以性能会下降,但是容错或者高可用加强了。所以需要在二者直接做权衡。如果说要求数据具备高可用,同时容错的时间花费比从新计算花费时间少,此时便可以使用,否则一般不用。
HEAP_OFF(experimental) 使用非Spark的内存,也即堆外内存,比如Tachyon,HBase、Redis等等内存来补充spark数据的缓存。
4、如何选择一款合适的持久化策略

第一就选择默认MEMORY_ONLY,因为性能最高嘛,但是对空间要求最高;如果空间满足不了,退而求其次,选择MEMORY_ONLY_SER,此时性能还是蛮高的,相比较于MEMORY_ONLY的主要性能开销就是序列化和反序列化;如果内存满足不了,直接跨越MEMORY_AND_DISK,选择MEMEORY_AND_DISK_SER,因为到这一步,说明数据蛮大的,要想提高性能,关键就是基于内存的计算,所以应该尽可能的在内存中存储对象;DISK_ONLY不用,xx_2的使用如果说要求数据具备高可用,同时容错的时间花费比从新计算花费时间少,此时便可以使用,否则一般不用。

二、共享变量

为了能够更加高效的在driver和算子之间共享数据,spark提供了两种有限的共享变量,一广播变量,二累加器。

1、broadcast广播变量

如果我们要在分布式计算里面分发大对象,例如:字典,集合,黑白名单等,这个都会由Driver端进行分发,一般来讲,如果这个变量不是广播变量,那么每个task就会分发一份,这在task数目十分多的情况下Driver的带宽会成为系统的瓶颈,而且会大量消耗task服务器上的资源,如果将这个变量声明为广播变量,那么只是每个executor拥有一份,这个executor启动的task会共享这个变量,节省了通信的成本和服务器的资源。

scala 复制代码
val list = List("hello hadoop")
//定义广播变量
val broadCast = sc.broadcast(list)
//调用
val data=broadCast.value

注意:

1、能不能将一个RDD使用广播变量广播出去?

不能,因为RDD是不存储数据的。可以将RDD的结果广播出去。

2、 广播变量只能在Driver端定义,不能在Executor端定义。

3、 在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值。

4、如果executor端用到了Driver的变量,如果不使用广播变量在Executor有多少task就有多少Driver端的变量副本。

5、如果Executor端用到了Driver的变量,如果使用广播变量在每个Executor中只有一份Driver端的变量副本。

2、accumulator累加器

accumulator累加器的概念和mr中出现的counter计数器的概念有异曲同工之妙,对某些具备某些特征的数据进行累加。累加器的一个好处是,不需要修改程序的业务逻辑来完成数据累加,同时也不需要额外的触发一个action job来完成累加

scala 复制代码
//构建一个累加器
val accu = sc.longAccumuator()
//累加的操作
accu.add(参数)
//获取累加器的结果,累加器的获取,必须需要action的触发
val ret = accu.value

注意:

1、累加器的调用,也就是accumulator.value必须要在action之后被调用,也就是说累加器必须在action触发之后。

2、多次使用同一个累加器,应该尽量做到用完即重置。accumulator.reset

3、尽量给累加器指定name,方便我们在web-ui上面进行查看。

三、RDD数据分区

Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数、RDD中每条数据经过Shuffle过程属于哪个分区和Reduce的个数。

分区的决定,就是在宽依赖的过程中才有,窄依赖因为是一对一或者一对常熟,分区确定的,所以不需要指定分区操作。

1、Partitioner

在Spark中涉及RDD的分区策略的抽象类为Partitioner,有两个核心的子类实现,一个HashPartitioner,一个RangePartitioner。Spark中数据分区的主要工具类(数据分区类),主要用于Spark底层RDD的数据重分布的情况中。

2、HashPartitioner

Spark中非常重要的一个分区器,也是默认分区器,默认用于90%以上的RDD相关API上。

功能:依据RDD中key值的hashCode的值将数据取模后得到该key值对应的下一个RDD的分区id值,支持key值为null的情况,当key为null的时候,返回0;该分区器基本上适合所有RDD数据类型的数据进行分区操作;但是需要注意的是,由于JAVA中数组的hashCode是基于数组对象本身的,不是基于数组内容的,所以如果RDD的key是数组类型,那么可能导致数据内容一致的数据key没法分配到同一个RDD分区中,这个时候最好自定义数据分区器,采用数组内容进行分区或者将数组的内容转换为集合。

3、RangePartitioner

SparkCore中除了HashPartitioner分区器外,另外一个比较重要的已经实现的分区器,主要用于RDD的数据排序相关API中,比如sortByKey底层使用的数据分区器就是RangePartitioner分区器;该分区器的实现方式主要是通过两个步骤来实现的,第一步:先从整个RDD中抽取出样本数据,将样本数据排序,计算出每个分区的最大key值,形成一个Array[KEY]类型的数组变量rangeBounds;第二步:判断key在rangeBounds中所处的范围,给出该key值在下一个RDD中的分区id下标;该分区器要求RDD中的KEY类型必须是可以排序的。

四、RDD依赖关系

1、依赖关系

RDD和它依赖的父RDD的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。

1、窄依赖(narrow dependency):指的是子RDD一个分区中的数据,来自于上游RDD中一个分区或者常数个分区。

2、宽依赖(wide dependency):指的是子RDD一个分区中的数据,来自于上游RDD所有的分区。

2、血统Lineage

RDD只支持粗粒度转换,即在大量记录上执行的单个操作。将创建RDD的一系列Lineage(即血统)记录下来,以便恢复丢失的分区。RDD的Lineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。

相关推荐
2501_943695337 分钟前
高职大数据技术专业,怎么参与开源数据分析项目积累经验?
大数据·数据分析·开源
Dxy12393102161 小时前
别再让 ES 把你拖垮!5 个实战技巧让搜索性能提升 10 倍
大数据·elasticsearch·搜索引擎
2501_943695331 小时前
大专市场调查与统计分析专业,怎么辨别企业招聘的“画饼”岗位?
大数据
七夜zippoe2 小时前
CANN Runtime跨进程通信 共享设备上下文的IPC实现
大数据·cann
威胁猎人2 小时前
【黑产大数据】2025年全球电商业务欺诈风险研究报告
大数据
L543414462 小时前
告别代码堆砌匠厂架构让你的系统吞吐量翻倍提升
大数据·人工智能·架构·自动化·rpa
证榜样呀2 小时前
2026 大专计算机专业必考证书推荐什么
大数据·前端
LLWZAI2 小时前
让朱雀AI检测无法判断的AI公众号文章,当创作者开始与算法「躲猫猫」
大数据·人工智能·深度学习
難釋懷2 小时前
分布式锁的原子性问题
分布式
SickeyLee3 小时前
产品经理案例分析(五):电商产品后台设计:撑起前台体验的 “隐形支柱”
大数据