• spark 学习(二) RDD及共享变量


    声明:本文基于spark的programming guide,并融合自己的相关理解整理而成

     

         Spark应用程序总是包括着一个driver program(驱动程序),它运行着用户的main方法,而且运行大量的并行操作(parallel operations)在集群上.

    概述


        Spark最基本的抽象就是RDD(resilient distributed dataset) 弹性分布式数据集,RDD  就是切割元素的集合,他被分发在集群的各个节点上,而且可以进行并行操作.
        RDD的创建有三种方式:
    • HDFS,HBase 或者其它不论什么可以提供Hadoop输入格式的数据源;          
    • 驱动程序中已存在的Scala集合;
    • 其它的RDD的转换
    RDD可以持久化到内存中以反复使用加速计算速度, RDD可以自己主动从失败的节点中恢复(血统设计).

        Spark中的还有一个抽象就是可以被用于并行计算的共享变量. 默认的情况下, Spark并行执行一个函数是作为一组tasks在不同的节点上同一时候计算的, 这样的情况下,他是通过分发每个变量的复制到每个task中的. 有时候,我们须要某些变量在tasks之间进行共享. 这里Spark支持两种共享变量:
    1.  broadcast variables, 被用于持久化变量在每一个node的内存中;
    2.  accumulators,  这个变量仅仅可以被累加,

        

    RDD操作


         操作主要包含两种,各自是transformations 和 action
         transformation : 将一个已经存在的RDD中转换成一个新的RDD,全部的转换操作都是lazy运行的,即仅仅是记下了运行的动作,仅仅有当driver程序须要结果的时候才会进行计算. 


    action:一般用于对RDD中的元素进行实际的计算,然后返回对应的值,比如reduce操作,collect操作,count操作等等.这中action之后返回的就不在是RDD了

    RDD基本操作的几个样例以及自己的理解:
     val conf = new SparkConf().setAppName("BasicRDDApp").setMaster("local[4]")
        //spark://host:port
        val sc = new SparkContext(conf)
    
        /**
         *  parallelized collections
         *  将scala的集合数据,并行化成为能够并行计算的分布式数据集
         */
        val data = 1 to 1000 toArray
        val distData = sc.parallelize(data,10)
        //后面的数字是表示将集合切分成多少个块 ,一般是一个CPU 2-4块,通常spark能够自己主动帮你切分
    
        val sum =  distData.reduce((a, b) => a+b )
        //在reduce的时候才開始真正的运行,driver将任务分布到各个机器上,然后每一个机器单独运行,将计算的结果返回到driver程序
        println("sum " + sum)
    
        /**
         * 读取外部的数据源
         * 1.Hadoop支持的数据源 ,比如HDFS,Cassandra,HBase ,Amazon S3
         * ##假设文件地址是本地地址的话,那么他应该在集群的每一个节点上都能够被訪问(即:每一个节点上都应该有相同的文件)
         * ##textFile的第二个參数控制文件被分割的大小默觉得64MB ,能够设置更大的可是不能设置更小的
         */
    
        val distFile = sc.textFile("file:///usr/local/spark/README.md")
    
        //接下来就能够进行相关的操作了
        distFile.persist()//持久化
    
        val len = distFile.map(s => 1).reduce((a, b) => a+b)
        println(len)
    
        val words = distFile.flatMap(l => l.split(" ")).map(w => (w,1)).reduceByKey((a,b) => a+b)
        //w => (v1+v2+v3+...)
        //map => 1->1 , flatMap => 1 -> 0..n
    
    
        print(words.count())
        words foreach println
    
        val twords = distFile.flatMap(l => l.split(" ")).map(w => (w,1)).groupByKey()
        //分组 w => (v1, v2, v3 ...)
    
        twords foreach println
        //.map(w => (w,1)).foreach(w => w._1);



    RDD的持久化


    1. 使用方法: 使用persist()或者cache()方法,当中cache()方法默认持久化到内存,persist能够自己选择持久化的层次,在shuffle操作中,spark会自己主动保存中间计算结果,比如reduceBykey
    2. 作用:  RDD的持久化会将会使得每一个节点保存对应的计算部分,以便再次使用该数据集时能够直接使用,加快计算速度
    3. 怎样选择持久化层次: 假设RDDs 在MEMORY_ONLY下表现良好的话,就选这个层次,这样CPU效率最高
      其次MEMORY_ONLY_SER ,其它情况http://spark.apache.org/docs/latest/programming-guide.html 



    共享变量


    1. broadcast 变量, 仅仅读的共享变量 每一个节点上都有一个拷贝, 使用方法
         val broadcastVar = sc.broadcast("string test")
         broadcastVar.value
    2.accumulator 变量,做累加器用,类似与counter或者是sum
        val broadcastVar = sc.broadcast("string test")//broadcast variable is readonly
    
        val v = broadcastVar.value
        println(v)
    
        val accum = sc.accumulator(0, "My Accumulator")//value and name
    
        sc.parallelize(1 to 1000000).foreach(x => accum+= 1)
    
        println(accum.name + ":" + accum.value)




  • 相关阅读:
    操作系统
    C++流类库(11)
    C++运算符重载(10)
    C++虚函数(09)
    C++向量(08)
    C++继承(07)
    ResNet实战
    ResNet,DenseNet
    经典卷积网络VGG,GoodLeNet,Inception
    CIFAR100与VGG13实战
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7299953.html
Copyright © 2020-2023  润新知