RDD Dependency

一般来说,分布式数据集的容错性有两种方式:数据检查点(Checkpoint)和记录数据的更新。由于面对大规模的数据分析,Checkpoint机制的操作成本会很高,故而spark选择通过记录数据更新的方式来提高容错率。但是如果更新粒度太细太多,那么记录更新成本也不低。因此,RDD只支持粗粒度转换,即只记录单个块上执行的单个操作,然后将创建RDD的一系列变换序列(每个RDD都包含了他是如何由其他RDD变换过来的以及如何重建某一块数据的信息。因此RDD的容错机制又称“血统(Lineage)”容错)记录下来,以便恢复丢失的分区。

Lineage(血统)机制:
与其他系统的内存数据更新的不同的是,RDD的lineage机制所记录的是特定数据的tranformation的操作(filter,map,join等)。当这个RDD的部分分区数据丢失时,它可以通过Lineage获取足够的信息来重新运算和恢复丢失的数据分区。因为这种粗颗粒的数据模型,限制了Spark的运用场合,所以Spark并不适用于所有高性能要求的场景,但同时相比细颗粒度的数据模型,也带来了性能的提升。

RDD在Lineage依赖方面分为了两种:完全依赖(narrow dependency)和部分依赖(shuffle dependency)
完全依赖和部分依赖的主要区别在于父RDD所对应的子RDD是多个(部分依赖)还是一个(完全依赖),当对应于多个子RDD的时候,在容错机制触发时,由于只需计算父RDD的一部分,会造成冗余计算。

对于部分依赖来说,Stage计算的输入和输出在不同的节点上,对于输入节点完好,而输出节点死机的情况,通过重新计算恢复数据这种情况下,这种方法容错是有效的,否则无效,因为无法重试,需要向上追溯其祖先看是否可以重试(这就是lineage,血统的意思),完全依赖对于数据的重算开销要远小于部分依赖的数据重算开销。

在容错机制中,如果一个节点死机了,而且运算完全依赖,则只要把丢失的父RDD分区重算即可,不依赖于其他节点。而部分依赖需要父RDD的所有分区都存在,重算就很昂贵了。可以这样理解开销的经济与否:在完全依赖中,在子RDD的分区丢失、重算父RDD分区时,父RDD相应分区的所有数据都是子RDD分区的数据,并不存在冗余计算。在部分依赖情况下,丢失一个子RDD分区重算的每个父RDD的每个分区的所有数据并不是都给丢失的子RDD分区用的,会有一部分数据相当于对应的是未丢失的子RDD分区中需要的数据,这样就会产生冗余计算开销,这也是部分依赖开销更大的原因。因此如果使用Checkpoint算子来做检查点,不仅要考虑Lineage是否足够长,也要考虑是否有部分依赖,对部分依赖加Checkpoint是最物有所值的。

你可能感兴趣的:(RDD Dependency)