01:上一篇部分回顾
https://blog.csdn.net/m0_57498038/article/details/119101404
-
Spark的功能、特点和应用场景是什么?
-
定义:Spark是一个光速的,统一化的数据分析分布式计算引擎和机器学习计算库
-
功能
-
离线批处理计算:SparkCore
-
离线交互式计算:SparkSQL
-
实时计算处理:SparkStreaming、StructStreaming
-
机器学习算法库:Spark ML lib
-
图计算:SparkGraphx
-
-
特点
-
非常快
-
好使:Java、Scala、Python、SQL、R
-
通用性:满足各种计算场景的需求
-
随处运行:数据源接口非常丰富 + 运行平台多样化【Standalone + YARN】
-
-
场景
-
离线计算场景:对Hive数据仓库中的数据进行处理转换
-
SparkCore + SparkSQL
-
-
-
-
Spark为什么比MapReduce要快?
-
Spark积极使用内存式计算:RDD
-
对于RDD的所有一对一的转换操作都是基于内存直接实现:不经过shuffle
-
-
Spark使用DAG:有向无环图的执行计划
-
灵活性
-
-
Spark中的Task是线程级别:节省进程的开销,只要启动一次,直到程序结束
-
-
Spark的架构是什么架构?
-
Standalone架构:分布式主从架构
-
主:Master:管理节点
-
管理从节点
-
接客
-
资源管理
-
-
从:Worker:计算节点
-
利用自己所在机器的资源运行Executor进程,实现Task的运行
-
-
-
Spark中的Driver和Executor是什么?
-
任何一个Spark程序都要包含两种进程
-
Driver进程:初始化进程或者Task管理进程
-
申请资源:启动Executor
-
Task的解析、分配调度、监控运行
-
-
Executor进程:执行进程
-
根据Worker分配的资源:CPU、内存
-
负责运行Driver所分配的Task的
-
-
-
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:学习目标
-
==Spark开发环境==
-
怎么在IDEA中开发Spark程序?=》本地测试代码逻辑
-
怎么将写好的代码打包放入集群运行?
-
Spark Standalone
-
Spark on YARN
-
-
整体程序运行过程的梳理:怎么解析Job,Stage,转换Task?
-
什么是deploymode?
-
面试题:Spark on YARN的时候不同deploymode有什么区别?
-
-
==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>