Spark之RDD内核原理,RDD的缓存机制,RDD算子优化之缓存优化

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用

目录

一、缓存的目的

二、缓存的方式

1,直接缓存

2,checkpoint

三、缓存的管理

1,自动清理

2,手动清理

四,两种缓存方式的区别

1,生命周期的区别

2,存储位置的区别

3,依赖关系

五、缓存的注意事项

1,内存管理

2,数据一致性

3,缓存的时机

六,总结


        在 Spark 中,RDD(Resilient Distributed Dataset,弹性分布式数据集)的缓存机制是一种重要的性能优化手段。以下是关于 RDD 缓存机制的详细介绍:

一、缓存的目的

        RDD 的缓存主要是为了提高 Spark 应用程序的性能。当一个 RDD 被多次使用时,如果每次都重新计算该 RDD,会消耗大量的时间和计算资源。通过缓存机制,可以将 RDD 存储在内存或磁盘中,以便在后续的操作中直接读取,避免重复计算,从而加快程序的执行速度。

缓存到内存之中

checkpoint缓存到HDFS中

二、缓存的方式

1,直接缓存

缓存是将数据存储在内存或者磁盘上,缓存的特点时,计算结束,缓存自动清空

  • 缓存级别

    • 指定缓存的数据位置

    • 默认是缓存到内存上

torageLevel.DISK_ONLY # 将数据缓存到磁盘上
StorageLevel.DISK_ONLY_2 # 将数据缓存到磁盘上 保存两份
StorageLevel.DISK_ONLY_3 # 将数据缓存到磁盘上 保存三份
StorageLevel.MEMORY_ONLY # 将数据缓存到内存  默认
StorageLevel.MEMORY_ONLY_2 # 将数据缓存到内存 保存两份
StorageLevel.MEMORY_AND_DISK # 将数据缓存到内存和磁盘  优先将数据缓存到内存上,内存不足可以缓存到磁盘
StorageLevel.MEMORY_AND_DISK_2 = # 将数据缓存到内存和磁盘
StorageLevel.OFF_HEAP # 不使用  缓存在系统管理的内存上   heap jvm的java虚拟机中的heap
StorageLevel.MEMORY_AND_DISK_ESER 
# 将数据缓存到内存和磁盘  序列化操作,按照二进制存储,节省空间

使用

  • persist 使用该方法

  • cache 内部调用persist

  • 手动释放 unpersist

# encoding=utf-8
from pyspark import SparkContext
from pyspark.storagelevel import StorageLevel

sc = SparkContext()

rdd = sc.parallelize(['a','b','c','d','a'])

res = rdd.map(lambda x:(x,1))
#缓存机制
res.persist(storageLevel=StorageLevel.MEMORY_AND_DISK)
#NameError: name 'StorageLevel' is not defined
print(res.collect())  #触发缓存

res1 = res.reduceByKey(lambda x,y:x+y)

print(res1.collect())






# 缓存 实现持久化
from pyspark import SparkContext
from pyspark.storagelevel import StorageLevel
sc = SparkContext()

# 获取数据
rdd = sc.textFile('hdfs://node1:8020/data/students.txt')
rdd_line = rdd.map(lambda x:x.split(','))
# 将数据转为kv结构  (gender,age)
def func(x):
    print('itcast')
    return (x[2],int(x[3]))

rdd_gender_age = rdd_line.map(func)

# 进入reduce阶段
# 统计不同性别的学生数量
# 先对kv数据进行分组
rdd_groupby = rdd_gender_age.groupByKey()
# 对分组后的结果进行缓存
# # storageLevel 修改缓存级别
rdd_groupby.persist(storageLevel=StorageLevel.MEMORY_AND_DISK)
# 触发缓存
rdd_groupby.collect()

# 获取kv数据中value部分数据
rdd_count = rdd_groupby.mapValues(lambda x:len(list(x)))
# 统不同性别年龄最大值
rdd_max = rdd_groupby.mapValues(lambda x:max(list(x)))
# 统计不同性别的年龄最小值
rdd_min = rdd_groupby.mapValues(lambda x:min(list(x)))
# 统计不同性别的平均年龄
rdd_avg = rdd_groupby.mapValues(lambda x:sum(list(x))/len(list(x)))

# 查看数据
res_count = rdd_count.collect()
print(res_count)
res_max = rdd_max.collect()
print(res_max)
res_min = rdd_min.collect()
print(res_min)
res_avg = rdd_avg.collect()
print(res_avg)

2,checkpoint

也是将中间rdd数据存储起来,但是存储的位置实时分布式存储系统,可以进行永久保存,程序结束不会释放

如果需要删除就在hdfs上删除对应的目录文件

# checkpoint 持久化  将数据存储在hdfs上
from pyspark import SparkContext

# 创建对象
sc = SparkContext()

# 指定checkpoint存储的hdfs位置
sc.setCheckpointDir('hdfs://node1:8020/checkpoint')

# 生成rdd数据
rdd = sc.parallelize(['hadoop,spark','spark,python'])

# 字符串数据切割
rdd_split = rdd.map(lambda x:x.split(','))  # [[hadoop,spark],[spark,python]]

# 将二维列表转为一维
def func(x):
    print('itheima')
    return x

rdd_word = rdd_split.flatMap(func) # [hadoop,spark,spark,python]
# 持久化操作,可以使用缓存或checkpoint
# # 对rdd使用checkpoint
rdd_word.checkpoint()
# rdd_word.persist()
# # # 触发执行
print(rdd_word.getCheckpointFile())


# 将数据转为kv
rdd_kv1 = rdd_word.map(lambda x:(x,1))

rdd_kv2 = rdd_word.map(lambda x:(x,2))

rdd_kv3 = rdd_word.map(lambda x:(x,3))

rdd_kv4 = rdd_word.map(lambda x:(x,4))

rdd_kv5 = rdd_word.map(lambda x:(x,5))


# 查看kv数据
res = rdd_kv1.collect()
print(res)
res2 = rdd_kv2.collect()
print(res2)
res3 = rdd_kv3.collect()
print(res3)
res4 = rdd_kv4.collect()
print(res4)
res5 = rdd_kv5.collect()
print(res5)
# encoding=utf-8

from pyspark import SparkContext

sc = SparkContext()

rdd =sc.parallelize(['a','b','c'',d','a'])

rdd_tup = rdd.map(lambda x:(x,1))

#缓存到hdfs上面  设置checkpoint缓存存放的位置
sc.setCheckpointDir('hdfs://node1:8020/checkpoint')
rdd_tup.checkpoint()
# 触发执行
print(rdd_tup.getCheckpointFile(),'有东西麽')
print(rdd_tup.collect())

三、缓存的管理

1,自动清理

  • Spark 会自动管理缓存的 RDD,当内存不足时,会根据一定的策略清理一些不再使用的 RDD,以释放内存空间。

  • 清理策略通常是基于 LRU(Least Recently Used,最近最少使用)算法,即优先清理最近最少使用的 RDD。

2,手动清理

  • 用户也可以手动清理缓存的 RDD,使用 unpersist() 方法可以将一个缓存的 RDD 从内存和磁盘中移除。

  • 在某些情况下,手动清理缓存可能是必要的,例如当缓存的 RDD 占用了大量的内存空间,而后续的操作不再需要这个 RDD 时。

四,两种缓存方式的区别

1,生命周期的区别

  • 直接缓存,程序计算结束之后自动删除
  • checkpoint  程序结束之后数据依然保留在HDFS中

2,存储位置的区别

  • 缓存 邮箱存储在内存之中,也可以选择存储在本地磁盘,是在计算任务所在的内存和磁盘上
  • checkpoint 存储在hdfs上

3,依赖关系

  • 缓存数据之后,会保留RDD之间的依赖关系, 缓存临时数据,数据可能会丢失,所以需要保留依赖,当缓存丢失后会按照原来的依赖重新计算
  • checkint,数据存储后会断开依赖,数据保存在hdfs中,hdfs的多副本机制可以保证数据不丢失,所以就没有必要保留依赖关系

五、缓存的注意事项

1,内存管理

  • 缓存 RDD 会占用内存空间,因此需要合理管理内存,避免内存溢出。可以通过调整 Spark 的内存参数,如 spark.executor.memory 和 spark.driver.memory,来控制可用内存的大小。

  • 同时,选择合适的存储级别也可以帮助管理内存。如果 RDD 较大,可以考虑使用磁盘缓存或序列化的方式来减少内存占用。

2,数据一致性

  • 当对一个缓存的 RDD 进行修改时,需要注意数据的一致性。如果多个操作同时对一个缓存的 RDD 进行修改,可能会导致数据不一致的问题。

  • 在这种情况下,可以使用 checkpoint 机制来创建一个检查点,将 RDD 的状态保存到可靠的存储系统中,如 HDFS。这样可以确保在出现故障时,能够从检查点恢复 RDD 的状态,保证数据的一致性。

3,缓存的时机

  • 并不是所有的 RDD 都需要缓存。只有那些会被多次使用的 RDD 才值得缓存。如果一个 RDD 只被使用一次,缓存它可能不会带来性能提升,反而会占用内存空间。

  • 因此,需要根据应用程序的实际情况,选择合适的时机进行缓存。可以在 RDD 被多次使用之前进行缓存,或者在一些关键的操作之前进行缓存,以提高性能。

六,总结

        总之,RDD 的缓存机制是 Spark 中一种重要的性能优化手段。通过合理地使用缓存机制,可以大大提高 Spark 应用程序的性能。在使用缓存时,需要注意内存管理、数据一致性和缓存的时机等问题,以确保应用程序的稳定和高效运行。

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值