「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
1.RDD的缓存
RDD缓存: 指的在整个执行链条中, 可以将那些计算比较复杂RDD 而且这些RDD需要被重复的使用, 此时可以提前将这个RDD的结果数据缓存起来, 这样后续在使用到这些RDD的时候, 就不需要在重新计算了, 直接从缓存中获取即可, 从而提升后续的执行效率
如何使用缓存操作呢?
1- 设置缓存: 大多数的情况, 我们都是使用persist 完成缓存操作, 更具有通用型
cache(); 触发缓存操作, 只会将数据缓存到内存中
persist([可选值: 设置缓存的级别]); 触发缓存的操作, 默认也是缓存到内存中, 支持自定义缓存的级别
2- 常用缓存的级别:
MEMORY_AND_DISK_2:将缓存数据优先存储到内存中, 如果内存不足的时候, 将剩余数据存储在磁盘中, 同时缓存副本数量为2份
MEMORY_AND_DISK_SER_2:将缓存数据优先存储到内存中, 如果内存不足的时候, 将剩余数据存储在磁盘中, 同时缓存副本数量为2份, 在缓存到内存的时候, 会对数据执行序列化的操作, 保证能够占用更小内存
MEMORT_ONLY: 表示只会将数据存储在内存中, 比较适合于内存充足的情况场景, 如果内存不足 是直接抛异常
注意:
1) 如果使用序列化的操作, 减少对内存空间占用, 但是提高对cpu占用, 因为需要cpu对数据进行序列化
2) 如果在生产中CPU资源比较充足, 建议使用带有ser的操作, 如果不足, 建议使用不带ser的
3) 缓存的API是一个转换算子, 需要使用缓存, 后续必须使用一个action算子进行触发, 一般来说都是使用count来触发即可
如何释放缓存:
unpersist()
代码演示操作:
from pyspark import SparkContext, SparkConf,StorageLevel
import os
import time
# 目的: 锁定远端操作环境, 避免存在多个版本环境的问题
os.environ["SPARK_HOME"] = "/export/server/spark"
os.environ["PYSPARK_PYTHON"] = "/root/anaconda3/bin/python"
os.environ["PYSPARK_DRIVER_PYTHON"] = "/root/anaconda3/bin/python"
if __name__ == '__main__':
print("测试 cache缓存操作")
# 1) 创建sparkContext对象
conf = SparkConf().setMaster("local[*]").setAppName("_cache_01")
sc = SparkContext(conf=conf)
# 2) 初始数据集的操作:
rdd_dataset = sc.parallelize(["张三 李四 王五", "李四 王五 赵六 李四", "张三 田七 赵六 赵六"])
# 3) 处理数据:
rdd_flatMap = rdd_dataset.flatMap(lambda line: line.split(" "))
# 如果给这个重复使用RDD 添加缓存后, 会发生什么情况呢?
rdd_flatMap.persist(storageLevel=StorageLevel.MEMORY_AND_DISK_2).count()
# 3.1: 求每个名字出现了多少次:
rdd_res = rdd_flatMap.map(lambda name: (name, 1)).reduceByKey(lambda agg, curr: agg + curr)
print(rdd_res.collect())
# 清除缓存
rdd_flatMap.unpersist()
print("=====================")
#3.2: 统计一共有多少个元素
print(rdd_flatMap.count())
print("=====================")
# 3.3: 统计一共有多少个不同的名字
print(rdd_flatMap.distinct().count())
time.sleep(100000)
# 4. 关闭 sc
sc.stop()
说明:
在测试缓存的使用的时候, 可以通过查看当前spark程序客户端界面. 通过这个界面查看缓存是否生效了, 如果看到执行DAG流程图中有一个小绿点, 表示缓存生效了, 如果都是黑点, 表示缓存没有生效
客户端地址:
node1:4040
注意:
每次启动前, 要保证前一个程序一定是停止的, 否则会导致 客户端地址的端口号从4040 不断更换端口号,
比如说; 第一次是4040 然后没有关闭, 再次启动, 端口号就会变更为 4041了, 依次类推
因为spark如果发现这个4040端口号被占用, 往后顺延 +1 ,所以在访问的时候, 如果4040无法访问, 尝试访问4041或者4042 等待..