「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」
RDD的checkpoint检查点
checkPoint: 可以将某一个阶段下的RDD的数据进行持久化的保存, 可以将数据保存在HDFS上, 来确保数据的可靠性, 一旦开启检查点后, 可以切断之前的RDD的依赖关系, 一旦后续出现问题的时候, 可以直接从checkpoint进行数据恢复即可, 不需要在重新计算检查点以前的内容了...
如何使用检测点呢?
1) 需要先设置检测点保存的位置
sc.setCheckpointDir("路径地址(必须是HDFS路径)")
2) 在需要开启检测点的RDD上, 执行开启操作:
rdd.checkpoint()
说明: checkpoint() 不需要触发, 自动默认会调用collect操作
3) 后续的rdd就可以直接从检测点恢复数据了...
代码实现:
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("测试checkpoint操作")
# 1) 创建sparkContext对象
conf = SparkConf().setMaster("local[*]").setAppName("_checkpoint_01")
sc = SparkContext(conf=conf)
# 设置checkpoint的保存的路径
sc.setCheckpointDir("/spark/checkpoint")
# 2) 初始数据集的操作:
rdd_dataset = sc.parallelize(["张三 李四 王五", "李四 王五 赵六 李四", "张三 田七 赵六 赵六"])
# 3) 处理数据:
rdd_flatMap = rdd_dataset.flatMap(lambda line: line.split(" "))
# 如果给这个重复使用RDD 添加checkpoint
rdd_flatMap.checkpoint() # 不需要调用, 自己触发, 本身自己内部会调用collect操作
# 3.1: 求每个名字出现了多少次:
rdd_res = rdd_flatMap.map(lambda name: (name, 1)).reduceByKey(lambda agg, curr: agg + curr)
print(rdd_res.collect())
print("=====================")
#3.2: 统计一共有多少个元素
print(rdd_flatMap.count())
print("=====================")
# 3.3: 统计一共有多少个不同的名字
print(rdd_flatMap.distinct().count())
time.sleep(100000)
# 4. 关闭 sc
sc.stop()
缓存和检测点的区别:
1) 存储位置:
缓存是将数据存储在内存或者磁盘上的
checkpoint是将数据存储在HDFS的
2) 生命周期:
缓存: 一旦程序停止掉或者手动调用unpersist() 都会调度缓存会被删除
checkpoint: 即使程序停止后, 依然可以在hdfs上看到这个数据, 不会被删除 (理解为保存了阶段快照)
3) RDD的血缘关系或者依赖关系:
缓存: 不会截断依赖关系, 整个依赖关系是维护着, 因为数据是存储在一些不是特别可靠的容器上, 一旦数据出现丢失, 可以通过回溯之前的流程, 重新计算
checkpoint: 会截断依赖关系, 因为数据是存储在hdfs这样可靠数据存储容器上, 基本认为不会发生数据丢失风险的,所以不需要回溯之前的流程, 也不需要重新计算