Spark之缓存策略

来源:互联网 发布:scada系统数据分析 编辑:程序博客网 时间:2024/06/05 14:51

一、使用读取文件来测试缓存策略的效率

package com.chb.java;import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.repl.SparkCommandLine;/** * 缓存策略 * @author 12285 * */public class Test {    public static void main(String[] args) {        SparkConf conf = new SparkConf().setAppName("hc").setMaster("local");        JavaSparkContext sc = new JavaSparkContext(conf);        //使用缓存策略与否, 测试效率        JavaRDD<String> lines = sc.textFile("IDCLog0012201704042133_45376.AVL");        //第一次Action        long beginTime = System.currentTimeMillis();        long count = lines.count();        System.out.println(count);        long endTime = System.currentTimeMillis();        System.out.println("cost " + (endTime - beginTime) + " milliseconds");        //第二次Action        beginTime = System.currentTimeMillis();        count = lines.count();        System.out.println(count);        endTime = System.currentTimeMillis();        System.out.println("cost " + (endTime - beginTime) + " milliseconds");        sc.close();    }}

二、不使用缓存策略

    JavaRDD<String> lines = sc.textFile("IDCLog0012201704042133_45376.AVL");

测试结果

#第一次Action用时142530cost 383 milliseconds#第二次Action用时142530cost 97 milliseconds

三、使用缓存策略.cache()

    JavaRDD<String> lines = sc.textFile("IDCLog0012201704042133_45376.AVL").cache();

测试结果

#第一次Action用时142530cost 499 milliseconds#第二次Action用时142530cost 27 milliseconds

两次对比,使用缓存策略的第二次用时27ms , 提高了499/27=18,使用的测试文件是26M, 效率大大提高了。

缓存策略的类StorageLevel

这里写图片描述

四、Lineage

RDD之间具有依赖关系, 像人类的血缘继承关系,

这里写图片描述

RDD的转换操作都是在内存中进行,如果在某个环节失败, 导致某个RDD丢失, 我们根据血统, 向上回溯, 找到所依赖的RDD, 但是,内存中的转化是稍纵即逝, 是无法找到的。

解决方法:

4.1、使用cache

如果我们将她的依赖RDD, 存到了cache中, 出现故障时, 可以根据血统依赖, 找到可能的最近的依赖RDD, 如:wordcount案例中, 我们将linesRDD进行了Cache, 失败的时候,不用再读取文件, 直接再cache中读取linesRDD, 这将省略了读取文件。节约了时间。

新的问题:如果进行缓存的RDD, 丢失了,怎么办? 由于缓存是在内存中进行的, 出现宕机,会导致缓存的RDD丢失

4.2、Lineage过长 ,对RDD进行doCheckPoint()

由于缓存也可能发生RDD丢失, 所以,将Lineage的某个RDD,将其存储到磁盘中,使用SparkContext.setCheckPointDir() 设置存储数据的路径。

五、Rdd 容错

Lineage(血统)

  利用内存加快数据加载,在众多的其它的In-Memory类数据库或Cache类系统中也有实现,Spark的主要区别在于它处理分布式运算环境下的数据容错性(节点实效/数据丢失)问题时采用的方案。为了保证RDD 中数据的鲁棒性,RDD数据集通过所谓的血统关系(Lineage)记住了它是如何从其它RDD中演变过来的。 相比其它系统的细颗粒度的内存数据更新级别的备份或者LOG机制,RDD的Lineage记录的是粗颗粒度的特定数据转换(Transformation)操作(filter, map, join etc.)行为。当这个RDD的部分分区数据丢失时 ,它可以通过Lineage获取足够的信息来重新运算和恢复丢失的数据分区。这种粗颗粒的数据模型,限制 了Spark的运用场合,但同时相比细颗粒度的数据模型,也带来了性能的提升。

  RDD在Lineage依赖方面分为两种Narrow Dependencies与Wide Dependencies用来解决数据容错的高 效性。

  • Narrow Dependencies是指父RDD的每一个分区最多被一个子RDD的分区所用(父分区和子分区一对一),表现为一个父 RDD的分区对应于一个子RDD的分区或多个父RDD的分区对应于一个子RDD的分区,也就是说一个父 RDD的一个分区不可能对应一个子RDD的多个分区。
  • Wide Dependencies是指子RDD的分区依赖于父 RDD的多个分区或所有分区,也就是说存在一个父RDD的一个分区对应一个子RDD的多个分区。对与 Wide Dependencies,这种计算的输入和输出在不同的节点上,lineage方法对与输入节点完好,而输出 节点宕机时,通过重新计算,这种情况下,这种方法容错是有效的,否则无效,因为无法重试,需要向上 其祖先追溯看是否可以重试(这就是lineage,血统的意思),Narrow Dependencies对于数据的重算开 销要远小于Wide Dependencies的数据重算开销。

容错

在RDD计算,通过checkpoint进行容错,做checkpoint有两种方式,一个是checkpoint data,一个是 logging the updates。用户可以控制采用哪种方式来实现容错,默认是logging the updates方式,通 过记录跟踪所有生成RDD的转换(transformations)也就是记录每个RDD的lineage(血统)来重新计算 生成丢失的分区数据

这里写图片描述

窄依赖和宽依赖的例子

  • Narrow Dependencies:是指父RDD的每一个分区最多被一个子RDD的分区所用(父分区和子分区一对一),表现为一个父 RDD的分区对应于一个子RDD的分区或多个父RDD的分区对应于一个子RDD的分区,也就是说一个父 RDD的一个分区不可能对应一个子RDD的多个分区。

  • Wide Dependencies:是指子RDD的分区依赖于父 RDD的多个分区或所有分区,也就是说存在一个父RDD的一个分区对应一个子RDD的多个分区。对与 Wide Dependencies,这种计算的输入和输出在不同的节点上,lineage方法对与输入节点完好,而输出 节点宕机时,通过重新计算,这种情况下,这种方法容错是有效的,否则无效,因为无法重试,需要向上 其祖先追溯看是否可以重试(这就是lineage,血统的意思),Narrow Dependencies对于数据的重算开 销要远小于Wide Dependencies的数据重算开销。

    这里写图片描述

0 0
原创粉丝点击