第一个问题:软件在设计时是怎么保证数据的安全性?
方案一:副本机制:将数据存储多份,每一份存在不同的节点上【内存一般不建议使用副本,内存小,而且易丢失】 hdfs
方案二:操作日志:记录内存的所有变化追加到一个日志文件中,可以通过日志文件进行恢复【日志数据量太大,恢复部分数据性能特别差】 namenode、redis
方案三:依赖关系:记录所有数据的来源,当数据丢失的时候,基于数据来源重新构建一份 spark
Spark的血缘机制(Lineage)是其容错设计的核心,通过记录数据转换的依赖关系而非存储中间数据实现高效容错。其运作机制如下:
一、血缘机制原理
-
依赖关系记录
每个RDD(弹性分布式数据集)存储其生成逻辑: $$ \text{RDD}\text{new} = f(\text{RDD} \text{parent}) $$ 例如:
textRDD = fileRDD.flatMap(lambda line: line.split(" ")) -
有向无环图(DAG)
所有转换操作构成依赖关系图:
graph LR A[原始RDD] --> B[Map操作] B --> C[Filter操作] C --> D[最终RDD]
二、容错实现流程
当节点故障导致分区丢失时:
- 回溯依赖链
根据血缘记录定位数据源头 - 重新计算
仅重算丢失分区的转换路径\\text{恢复时间} \\propto \\text{依赖链长度}
三、技术优势
- 空间高效
避免数据复制,节省存储成本 - 计算优化
支持检查点(Checkpoint)缩短依赖链T_\\text{recovery} = \\min(T_\\text{full_compute}, T_\\text{checkpoint})
案例 :过滤大文件时仅需记录filter(func)的转换逻辑,故障后直接从源文件重新执行过滤,无需备份中间数据。