RDD的checkpoint检查点以及与缓存的区别

338 阅读2分钟

「这是我参与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这样可靠数据存储容器上, 基本认为不会发生数据丢失风险的,所以不需要回溯之前的流程, 也不需要重新计算