Spark:Core(一)

01:上一篇部分回顾

https://blog.csdn.net/m0_57498038/article/details/119101404

  1. Spark的功能、特点和应用场景是什么?

    • 定义:Spark是一个光速的,统一化的数据分析分布式计算引擎和机器学习计算库

    • 功能

      • 离线批处理计算:SparkCore

      • 离线交互式计算:SparkSQL

      • 实时计算处理:SparkStreaming、StructStreaming

      • 机器学习算法库:Spark ML lib

      • 图计算:SparkGraphx

    • 特点

      • 非常快

      • 好使:Java、Scala、Python、SQL、R

      • 通用性:满足各种计算场景的需求

      • 随处运行:数据源接口非常丰富 + 运行平台多样化【Standalone + YARN】

    • 场景

      • 离线计算场景:对Hive数据仓库中的数据进行处理转换

        • SparkCore + SparkSQL

  2. Spark为什么比MapReduce要快?

    • Spark积极使用内存式计算:RDD

      • 对于RDD的所有一对一的转换操作都是基于内存直接实现:不经过shuffle

    • Spark使用DAG:有向无环图的执行计划

      • 灵活性

    • Spark中的Task是线程级别:节省进程的开销,只要启动一次,直到程序结束

  3. Spark的架构是什么架构?

    • Standalone架构:分布式主从架构

    • 主:Master:管理节点

      • 管理从节点

      • 接客

      • 资源管理

    • 从:Worker:计算节点

      • 利用自己所在机器的资源运行Executor进程,实现Task的运行

  4. Spark中的Driver和Executor是什么?

    • 任何一个Spark程序都要包含两种进程

    • Driver进程:初始化进程或者Task管理进程

      • 申请资源:启动Executor

      • Task的解析、分配调度、监控运行

    • Executor进程:执行进程

      • 根据Worker分配的资源:CPU、内存

      • 负责运行Driver所分配的Task的

  5. Spark中的Task是怎么得到的?

    • step1:先读取数据:将数据变成一个RDD【分布式的集合】对象

    • step2:转换处理数据:将RDD不断调用转换函数进行处理,得到新的RDD

    • step3:将结果进行保存

    • Job:触发job,当用到RDD中的数据的时候,根据RDD的来源转换关系,构建DAG

    • Stage:一个Job划分多个Stage,Stage编号是按照APP全局编号的,根据是否产生Shuffle来划分Stage

      • 为什么要根据shuffle划分Stage?

        • 同一个Stage中的所有Task可以在内存中并行运行

    • Task:每个Stage会对应一定个数的Task,Task个数由Stage中RDD的分区个数决定

02:学习目标

  1. ==Spark开发环境==

    • 怎么在IDEA中开发Spark程序?=》本地测试代码逻辑

    • 怎么将写好的代码打包放入集群运行?

      • Spark Standalone

      • Spark on YARN

    • 整体程序运行过程的梳理:怎么解析Job,Stage,转换Task?

    • 什么是deploymode?

    • 面试题:Spark on YARN的时候不同deploymode有什么区别?

  2. ==RDD的设计==

    • RDD是什么?

    • RDD的五大特性是什么?

03:Spark应用开发:IDEA环境

  • 目标实现Spark应用开发IDEA环境配置

  • 实施

    • 创建工程模块

    • 添加Scala支持

    • 引入依赖

      • 参考附录一

    • 添加测试数据

  • 小结

    • 实现Spark应用开发IDEA环境配置

04:Spark应用开发:基础模板

  • 目标实现SparkCore程序的基础模板开发

  • 实施

    package bigdata.cn.spark.core.mode
    ​
    import org.apache.spark.{SparkConf, SparkContext}
    ​
    /**
      * @ClassName SparkCoreSimpleMode
      * @Description TODO SparkCore 程序的基础模板
     */
    object SparkCoreSimpleMode {
    ​
      def main(args: Array[String]): Unit = {
        //todo:1-构建SparkContext对象
        val sc:SparkContext = {
          //构建SparkConf配置管理对象,类似于Hadoop中的Configuration对象
          val conf = new SparkConf()
              .setMaster("local[2]")//指定运行模式
              .setAppName(this.getClass.getSimpleName.stripSuffix("$"))//指定运行程序名称
    //          .set("key","value") //指定额外的属性
          //返回SparkContext对象
          SparkContext.getOrCreate(conf)
        }
        //调整日志级别
        sc.setLogLevel("WARN")
    ​
        //todo:2-实现数据的转换处理
        //step1:读取数据
        //step2:处理数据
        //step3:保存结果
    ​
        //todo:3-释放SparkContext对象
        sc.stop()
      }
    }
     
  • 小结

    • 实现SparkCore程序的基础模板开发

05:Spark应用开发:WordCount实现

  • 目标基于SparkCore程序的开发模板实现WordCount的开发

  • 实施

    package bigdata.cn.spark.core.wordcount
    ​
    import org.apache.spark.rdd.RDD
    import org.apache.spark.{SparkConf, SparkContext}
    ​
    /**
      * @ClassName SparkCoreWordCount
      * @Description TODO SparkCore 实现词频统计
      */
    object SparkCoreWordCount {
    ​
      def main(args: Array[String]): Unit = {
        //todo:1-构建SparkContext对象
        val sc:SparkContext = {
          //构建SparkConf配置管理对象,类似于Hadoop中的Configuration对象
          val conf = new SparkConf()
              .setMaster("local[2]")//指定运行模式
              .setAppName(this.getClass.getSimpleName.stripSuffix("$"))//指定运行程序名称
    //          .set("key","value") //指定额外的属性
          //返回SparkContext对象
          SparkContext.getOrCreate(conf)
        }
        //调整日志级别
        sc.setLogLevel("WARN")
    ​
        //todo:2-实现数据的转换处理
        //step1:读取数据
        val inputRdd: RDD[String] = sc.textFile("datas/wordcount/wordcount.data")
    //    println(s"总行数=${inputRdd.count()}")
    //    println(s"第一行=${inputRdd.first()}")
        
        //step2:处理数据
        val wcRdd: RDD[(String, Int)] = inputRdd
          .filter(line => line != null && line.trim.length > 0)//过滤
          .flatMap(line => line.trim.split("\\s+")) //将每个单词提取
          .map(word => (word,1)) //构建二元组keyvalue
          .reduceByKey((tmp,item) => tmp+item) //按照key进行分组聚合
    ​
        //step3:保存结果
        wcRdd.foreach(println)
    ​
        //todo:3-释放SparkContext对象
        Thread.sleep(1000000000L)
        sc.stop()
      }
    }

     

  • 小结

    • 基于SparkCore程序的开发模板实现WordCount的开发

06:Spark应用开发:TopKey:sortBy

  • 目标基于SparkCore中的sortBy算子实现的WordCount的TopKey

  • 实施

    • sortBy的功能与语法

      def sortBy[K](
            f: (T) => K,
            ascending: Boolean = true,
            numPartitions: Int = this.partitions.length)
            (implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T]
      • 功能:实现排序

      • 语法

        • 参数

          • 函数:指定按照谁排序

          • 升序还是降序:默认true为升序

          • 指定分区个数:默认与调用的RDD的分区个数一致

        • 返回值:RDD

    • Topkey实现

      //step2:处理数据
          val wcRdd: RDD[(String, Int)] = inputRdd
            .filter(line => line != null && line.trim.length > 0)//过滤
            .flatMap(line => line.trim.split("\\s+")) //将每个单词提取
            .map(word => (word,1)) //构建二元组keyvalue
            .reduceByKey((tmp,item) => tmp+item) //按照key进行分组聚合
      
            //方式一:sortBy
            .sortBy(tuple => tuple._2,false) //第一个参数:按照是排序,第二个参数是升序还是降序
            .sortBy(tuple => -tuple._2) //第一个参数:按照是排序,第二个参数是升序还是降序
      

    • 问题:为什么sortBy操作会产生job?

      • 什么时候会触发Job的运行?

        • 当真正需要使用数据的时候,就会触发job的运行

      • 为什么sortBy会触发呢?

        • sortBy会经过shuffle过程:Shuffle时候是会有分区规则

        • Spark中自带了两种分区

          • Hash分区:与MapReduce基本一致,默认的分区基本都是Hash分区

          • 采样分区:==sortBy使用了采样分区==【对数据进行采样读取,再进行怎么分区】

        • 为什么sortBy要使用采样分区?

          • 因为多个Task并发的情况下要想==实现全局有序==

          • 必须保证下一个分区的最小值要大于上一个分区的最大值

  • 小结

    • 基于SparkCore中的sortBy算子实现的WordCount的TopKey

07:Spark应用开发:TopKey:sortByKey

  • 目标基于SparkCore中的sortByKey算子实现的WordCount的TopKey

  • 实施

    • sortByKey的功能与语法

      def sortByKey(ascending: Boolean = true, 
      numPartitions: Int = self
      .partitions.length)
            : RDD[(K, V)]
      • 功能:实现二元组类型的RDD按照Key排序

      • 参数

        • 升序或者降序:默认升序

        • 分区个数:默认为调用RDD的分区个数

      • 返回值

        • 排序好的新RDD

    • Topkey实现

            //方式二:sortByKey
            .map(tuple => tuple.swap) //将单词的个数作为Key
            .sortByKey(false) //默认按照key排序
      
            //取前4
            wcRdd.take(4).foreach(println)

    • take的功能与用法

      • 功能:取RDD集合中的数据放入一个数组中,返回Driver中

        • 通过单个线程从RDD的每个分区中取想要的数据

      • 参数:N,返回前N条

      • 返回值:数组

  • 小结

    • 基于SparkCore中的sortByKey算子实现的WordCount的TopKey

08:Spark应用开发:TopKey:top

  • 目标基于SparkCore中的top算子实现的WordCount的TopKey

  • 实施

    • top的功能与语法

      def top(num: Int)(implicit ord: Ordering[T]): Array[T]

      • 功能:专门自动做排序取前N名的值,默认就是降序

      • 语法

        • 参数

          • num:取前N名

          • ord:隐式参数,可以不给,默认按照整体进行排序

        • 返回值:数组

      • 应用:只适合对小数据量的数据排序

      • 原理:将RDD所有分区的数据放入一个数组中,这个数组是存储在Driver进程的内存中

    • Topkey实现

      //方式三:top:专门自动做排序取前N名的值,默认就是降序
              .top(4)(Ordering.by(tuple => tuple._2))

    • 问题:三个算子的性能哪个更好?

      • 小数据量:Top的性能更好

      • 大数据量:sortBy或者sortByKey + Take

  • 小结

    • 基于SparkCore中的top算子实现的WordCount的TopKey

09:jar包运行:场景及spark-submit

  • 目标掌握jar包的应用场景及spark-submit脚本的使用

  • 路径

    • step1:应用场景

    • step2:spark-submit的使用

  • 实施

    • 应用场景

      • IDEA运行:测试代码逻辑

      • 集群运行:测试环境和生产使用

    • spark-submit的使用

      • 用法

        #提交运行jar包
        Usage: spark-submit [options] <app jar | python file | R file> [app arguments]
        
        #终止一个Spark程序
        Usage: spark-submit --kill [submission ID] --master [spark://...]
        
        #查询程序的状态
        Usage: spark-submit --status [submission ID] --master [spark://...]
        
        spark-submit \
        选项:master、mainClass、资源选项
        spark-wc.jar \
        /example/wc.data \
        /output/wc

      • 基本选项

        • --master:指定spark程序运行环境

          • local:本地

          • spark://node1:7077:Standalone集群

          • yarn:YARN集群

        • --deploy-mode:决定了Driver进程运行在本地还是某一台Worker节点上

        • --name:指定程序的名称

        • --class:指定运行哪个类

        • --jars:指定第三方jar包

        • --conf:指定配置

      • driver资源选项

        • --driver-memory:分配给Driver的内存,默认分配1GB

        • --driver-cores:分配给Driver运行的CPU核数,默认分配1核

        • --supervise:故障自动重启

      • Executor资源选项

        • --executor-memory:分配给每个Executor的内存数,默认为1G,所有集群模式都通用的选项

        • --executor-cores:分配给每个Executor的核心数,YARN集合和Standalone集群通用的选项

          • YARN :默认每个Executor分配1core

          • Standalone:默认分配所有可用的核数给每个Executor

        • --total-executor-cores NUM:Standalone模式下用于指定所有Executor所用的总CPU核数

          • 总核数 / 每个Executor核数 = Executor的个数

        • --num-executors NUM:YARN模式下用于指定Executor的个数,默认启动2个

  • 小结

    • 掌握jar包的应用场景及spark-submit脚本的使用

10:jar包运行:本地提交

  • 目标实现Spark应用程序jar包的本地提交

  • 实施

    • 提交命令

      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master local[2] \
      --class bigdata.cn.spark.core.wordcount.SparkCoreWordCount \
      ~/spark-wc.jar \
      /example/wc.data \
      /output/wc

    • 运行结果

    •  

  • 小结

    • 实现Spark应用程序jar包的本地提交

11:jar包运行:Standalone集群提交

  • 目标:实现Spark应用程序jar包的集群提交

  • 路径

    • step1:上传jar包

    • step2:提交命令

    • step3:运行结果

    • step4:指定资源

  • 实施

    • 上传jar包

      hdfs dfs -mkdir -p /spark/apps
      hdfs dfs -put spark-wc.jar /spark/apps

    • 提交命令

      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master spark://node1:7077 \
      --class bigdata.cn.spark.core.wordcount.SparkCoreWordCount \
      hdfs://node1:8020/spark/apps/spark-wc.jar \
      /example/wc.data \
      /output/wc

    • 运行结果

      • 问题1:为什么启动了3个Executor,每个Executor用了1Core1GB?

        • 默认参数值,没有值,每个Worker就是1Core1GB

      • 问题2:为什么本地模式,会打印结果,显示在命令行,而集群模式没有显示?

        • 本地模式:只有1个进程:Driver,Task运行在Driver,直接做交互返回结果

        • 集群模式:所有Task的运行Executor中,每个Executor运行在不同的机器上,在不同机器的Executor进程中输出

    • 指定资源

      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master spark://node1:7077 \
      --class bigdata.cn.spark.core.wordcount.SparkCoreWordCount \
      --driver-memory 512M \
      --executor-memory 512M \
      --executor-cores 1 \
      --total-executor-cores 2 \
      hdfs://node1:8020/spark/apps/spark-wc.jar \
      /example/wc.data \
      /output/wc

       

  • 小结

    • 实现Spark应用程序jar包的集群提交

12:基本运行流程梳理

  • 目标:掌握Spark程序运行的基本流程

  • 路径

    • step1:Driver及Executor的启动

    • step2:Main方法的执行

    • step3:Task的解析分配

  • 实施

    • step1:Driver及Executor的启动

      • 程序运行启动Driver,默认启动客户端那台机器上

      • Driver向Master申请资源

      • 根据提交的申请,Master会在Worker上启动Executor进程

      • 所有Executor会向Driver反向注册

    • step2:Main方法的执行

      • Driver开始解析Main方法开始的代码

      • 代码中出现RDD数据的使用,就会触发job

      • job触发后,通过回溯算法对RDD的转换构建DAG图

        • 回溯算法:倒推

        • 每遇到一个Shuffle就划分一个Stage

    • step3:Task的解析分配

      • 根据DAG从编号最小的Stage开始,转换为Task,

      • 每一个Stage会转换为一个TaskSet集合,TaskSet集合中会有多个Task

      • Driver将TaskSet中的Task分配调度到Executor中执行

  • 小结

    • 掌握Spark程序运行的基本流程

13:Spark on YARN:应用场景及配置

  • 目标:了解Spark on YARN的应用场景及环境配置

  • 路径

    • step1:应用场景

    • step2:环境配置

  • 实施

    • 应用场景

      • 分布式计算 = 分布式程序【MR,Spark】 + 分布式运行环境【YARN,Standalone】

      • 分布式资源容器:分布式资源管理平台,用于实现将多台机器的物理资源从逻辑上进行合并,构建成一个大的资源容器,来运行分布式程序

        • YARN

        • Standalone

      • 需求:为了避免同一套物理资源由多套资源管理平台管理,导致管理混乱,一般在工作中选择使用一种公共的资源管理平台来实现

      • 解决:将所有分布式计算程序全部提交在YARN上来实现运行

    • 环境配置

      • 修改yarn-site.xml

        <property>
        	    <name>yarn.log-aggregation-enable</name>
        	    <value>true</value>
        </property>
        <property>
        	    <name>yarn.log-aggregation.retain-seconds</name>
        	    <value>604800</value>
        </property>
        <property>
                <name>yarn.log.server.url</name>
                <value>http://node1:19888/jobhistory/logs</value>
        </property>
        <property>
        	    <name>yarn.nodemanager.pmem-check-enabled</name>
        	    <value>false</value>
        </property>
        <property>
        	    <name>yarn.nodemanager.vmem-check-enabled</name>
        	    <value>false</value>
        </property>

      • 分发

        cd /export/server/hadoop/etc/hadoop
        scp -r yarn-site.xml root@node2:$PWD
        scp -r yarn-site.xml root@node3:$PWD

      • 关闭Spark集群

        cd /export/server/spark
        sbin/stop-master.sh
        sbin/stop-slaves.sh
        sbin/stop-history-server.sh

      • 修改spark-env.sh

        #添加yarn的地址
        YARN_CONF_DIR=/export/server/hadoop/etc/hadoop

      • 配置HDFS上Spark jar包的存储位置:解决YARN运行Spark没有Spark的依赖包

        hdfs dfs -mkdir -p /spark/apps/jars/
        hdfs dfs -put /export/server/spark/jars/* /spark/apps/jars/

      • 修改spark-defaults.conf

        #为了在8088中能直接访问Spark程序的监控,所以这里这里做了转接,如果在yarn中点击history,就转接18080
        spark.yarn.historyServer.address   node1:18080
        #指定yarn运行时的spark的jar包的地址
        spark.yarn.jars  hdfs://node1:8020/spark/apps/jars/*

      • 分发

        cd /export/server/spark/conf/
        scp spark-env.sh spark-defaults.conf node2:$PWD
        scp spark-env.sh spark-defaults.conf node3:$PWD

  • 小结

    • 了解Spark on YARN的应用场景及环境配置

14:Spark on YARN:运行测试

  • 目标:实现Spark on YARN程序的运行测试

  • 实施

    • 启动环境

      • 启动YARN:第一台机器启动

        start-yarn.sh

      • 启动Jobhistoryserver

        mr-jobhistory-daemon.sh start historyserver
        • 只能记录MapReduce在YARN上运行的程序

        • 端口:19888

      • 启动Spark的HistoryServer

        /export/server/spark/sbin/start-history-server.sh 
        • 记录spark在yarn上运行的程序

        • 端口:18080

    • 提交命令

      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master yarn \
      --class bigdata.spark.core.wordcount.SparkCoreWordCount \
      hdfs://node1:8020/spark/apps/spark-wc.jar \
      /example/wc.data \
      /output/wc
      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master yarn \
      --class bigdata.spark.core.wordcount.SparkCoreWordCount \
      --driver-memory 512M \
      --executor-memory 512M \
      --executor-cores 1 \
      --num-executors 1 \
      hdfs://node1:8020/spark/apps/spark-wc.jar \
      /example/wc.data \
      /output/wc

    • 运行结果

  • 小结

    • 实现Spark on YARN程序的运行测试

15:Spark on YARN:MR提交过程回顾

  • 目标:回顾MapReduce程序在YARN上的运行流程

  • 实施

    • step1:客户端提交程序给ResourceManager

    • step2:ResourceManager会随机选择一台NodeManger去启动一个特殊进程:==AppMaster==

  • step3:AppMaster会向ResourceManger申请运行资源

    • step4:ResourceSchedule负责分配资源给AppMaster:Container【包含了资源的进程】

  • step5:APPMaster根据RM分配的Container在对应的NodeManger上运行Container,启动Task进程

    • step6:NodeManger按照APPmaster通知在自己的节点上启动MapTask和ReduceTask

  • step7:所有Task在运行过程中都必须向APPMaster进行汇报

    • step8:所有Task运行结束,汇报给ResourceManager

  • 类比

    • APPMaster功能:运行在NodeManager上,负责申请资源,监控Task运行,返回结果

    • 相当于Driver

    • MapTask和ReduceTask:由RM分配,运行NodeManager上进程

    • 相当于Executor

  • 小结

    • 回顾MapReduce程序在YARN上的运行流程

16:DeployMode

  • 目标掌握Spark中deploymode的功能

  • 路径

    • step1:问题

    • step2:功能

    • step3:测试

  • 实施

    • 问题

      • Driver和Executor是Spark程序运行的两种核心进程,Executor运行在Worker节点上,Driver运行在哪?

    • 功能

      • 决定了driver运行的节点的位置

        --deploy-mode DEPLOY_MODE   Whether to launch the driver program 
        locally ("client") or
                                 on one of the worker machines inside 
        the cluster ("cluster")
                                      (Default: client).

      • client模式:Driver进程运行本地客户端,默认模式

      • cluster模式:Driver进程随机运行在Worker节点上

      • 问题:如果一直使用client模式,所有Spark程序的driver都运行在同一台机器,导致机器的负载比较高,Driver故障率就比较高,性能比较差

    • 测试

      • client

        SPARK_HOME=/export/server/spark
        ${SPARK_HOME}/bin/spark-submit \
        --master spark://node1:7077 \
        --class bigdata.spark.core.wordcount.SparkCoreWordCount \
        hdfs://node1:8020/spark/apps/spark-wc.jar \
        /example/wc.data \
        /output/wc
        SPARK_HOME=/export/server/spark
        ${SPARK_HOME}/bin/spark-submit \
        --master spark://node1:7077 \
        --deploy-mode client \
        --class bigdata.spark.core.wordcount.SparkCoreWordCount \
        hdfs://node1:8020/spark/apps/spark-wc.jar \
        /example/wc.data \
        /output/wc

         

      • cluster

        SPARK_HOME=/export/server/spark
        ${SPARK_HOME}/bin/spark-submit \
        --master spark://node1:7077 \
        --deploy-mode cluster \
        --class bigdata.spark.core.wordcount.SparkCoreWordCount \
        hdfs://node1:8020/spark/apps/spark-wc.jar \
        /example/wc.data \
        /output/wc

        • Driver运行在Worker使用了Worker的资源

         

  • 小结

    • 什么是deploymode,client与cluster的区别是什么?

      • 功能:决定driver运行的位置

      • 选择

        • client:默认,driver运行客户端,直接使用客户端机器的资源

        • cluster:driver运行Worker节点上,使用Worker的资源

17:Spark on YARN:DeployMode区别

  • 目标掌握Spark on YARN模式下deploymode的区别

  • 路径

    • step1:YARN上进程分类

    • step2:Spark on YARN 的Client模式

    • step2:Spark on YARN 的Cluster模式

  • 实施

    • YARN上进程分类

      • AppMaster,应用管理者,申请资源和调度Job执行

      • Process,运行在NodeManager上进程,运行Task

        • 如果是MapReduce运行YARN上,就是 MapTask和ReduceTask

        • 如果是Spark运行YARN上,就是Executors

    • Spark上进程分类

      • Driver Program,应用管理者,申请资源运行Executors和调度Job执行

      • Executors,运行JVM进程,其中执行Task任务和缓存数据

    • Spark on YARN 的Client模式

      • AppMaster:申请资源,运行Executors

        • 运行在NodeManager

      • Driver Program:调度Job执行和监控

        • 运行在客户端机器

      • Executors:运行JVM进程,其中执行Task任务和缓存数据

    • Spark on YARN 的Cluster模式

      • Driver Program(AppMaster):既进行资源申请,又进行Job调度

      • Executors:运行JVM进程,其中执行Task任务和缓存数据

  • 小结

    • Spark on YARN时,deploymode的client模式与cluster模式有什么区别?

      • client:driver和APPMaster共存

        • driver运行在客户端机器:负责Task解析、调度和监控

        • AppMaster运行NodeManager上:负责资源申请

      • cluster:driver和AppMaster合并了

18:RDD:功能与设计

  • 目标掌握RDD的功能与设计

    • RDD是什么?

  • 实施

    Spark revolves around the concept of a resilient distributed dataset (RDD), which is a fault-tolerant collection of elements that can be operated on in parallel. There are two ways to create RDDs: parallelizing an existing collection in your driver program, or referencing a dataset in an external storage system, such as a shared filesystem, HDFS, HBase, or any data source offering a Hadoop InputFormat.

    • 定义:弹性分布式数据集【Resilient Distributed Datasets 】

      • 本质:数据集合

      • 分布式:拥有多个分区的数据集合

    • 功能:实现计算过程中数据的存储

      • step1:读取任何数据进入程序,数据都放入一个RDD1中

      • step2:对RDD1进行处理转换得到RDDN

    • 设计

      • RDD的并行化的操作

        • RDD是有多个分区来实现分布式存储

      • RDD具有优秀的容错能力:弹性

        • RDD是一个逻辑的概念:物理上多个分区从逻辑上合并为一个RDD

          rdd1:{1,2,3,4}
          	part0:1,2
          	part1:3,4
          
          rdd2 = rdd1.map(_*2) : {2,4,6,8}
          	task0:part0 * 2
              	rdd2:Part0:{2,4}
          	task1:part1 * 2
          		rdd2:Part1:{6,8}

        • RDD的物理分区存储这个RDD的数据:Executor的内存中

        • 缺点:易丢失

          • 副本机制:将内存的数据构建一份副本【内存副本,磁盘副本】

          • 持久化:HDFS

        • ==核心:RDD的血脉关系==

          • 每个RDD都会记录自己的来源

    • 实现

      • 任何的数据源,通过Spark读取以后,都可以分布式的存储在RDD中

      • 调用RDD的函数对RDD的数据进行处理:直接对RDD的每个分区进行处理

  • 小结

    • RDD是什么?

      • 弹性具有优秀容错能力的分布式基于分区并行化操作数据集合

19:RDD:五大特性

  • 目标掌握RDD五大特性

  • 实施

    • 特性一:A list of partitions

    •  

      • 每个RDD可以由一系列的分区构成

      • RDD是分布式的数据集合

    • 特性二:A function for computing each split

      • 对RDD的函数操作,本质是对RDD每个分区的函数计算

      • RDD的转换时基于分区的并行化操作

    • 特性三:A list of dependencies on other RDDs

      • 每个RDD都会保存与其他RDD之间的依赖关系:血链或者血脉

        • RDD4

        • |

        • RDD3.map

        • |

        • RDD2.flatMap

        • |

        • RDD1:sc.textFile

    • 特性四:Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)

      • 可选的,如果是二元组类型的RDD,可以自定义分区器

        • Shuffle时候调用分区器

        • 默认的分区器

          • hash分区

          • 范围分区:采样

    • 特性五:Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)

      • 可选的,Spark程序运行时,可以指定实现最优路径解:最优计算位置

      • 设计概念:移动存储不如移动计算

      • 级别

        • level1:当前要处理的数据所在的Executor中运行

        • level2:运行同一台机器的另外一个Executor

        • level3:在另外一台机器的Executor中运行

        • level4:Any

  • 小结

    • RDD的五大特性分别是什么?

      • 1-每个RDD由多个分区构成

      • 2-对RDD的处理转换,本质是上RDD每个分区的转换操作

      • 3-每个子RDD都会记录与父RDD的依赖关系

      • 4-可选的,二元组KV类型的RDD在经过shuffle过程时可以自定义分区器

      • 5-可选的,Spark的Task在分配时,根据数据所在的位置计算最优路径解

20:RDD:WordCount中的RDD

  • 目标:基于RDD的功能和设计以及五大特性,了解WordCount中的RDD的实现

  • 实施

    • RDD是immutable,不可变

    • 所有RDD的转换返回的是一个新的RDD

  • 小结

    • 基于RDD的功能和设计以及五大特性,了解WordCount中的RDD的实现

附录一:Spark Maven依赖

<!-- 指定仓库位置,依次为aliyun、cloudera和jboss仓库 -->
    <repositories>
        <repository>
            <id>aliyun</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.com/nexus/content/groups/public</url>
        </repository>
    </repositories>

    <properties>
        <scala.version>2.11.12</scala.version>
        <scala.binary.version>2.11</scala.binary.version>
        <spark.version>2.4.5</spark.version>
        <hadoop.version>2.6.0-cdh5.16.2</hadoop.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_${scala.binary.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
    </dependencies>

    <build>
        <outputDirectory>target/classes</outputDirectory>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
            </resource>
        </resources>
        <!-- Maven 编译的插件 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值