Spark基础和RDD

本文详细介绍了Spark在Yarn上的两种部署模式——client和cluster,包括各自的优缺点和适用场景。接着,讲解了spark-submit命令的使用以及PySpark程序与Spark的交互流程,包括client和cluster模式下Driver的启动和执行过程。此外,文章还概述了RDD的基本概念、特性以及如何构建和管理RDD的分区数量。
摘要由CSDN通过智能技术生成

目录

一、Spark On Yarn两种部署方式

二、spark-submit命令

三、PySpark程序与Spark交互流程

1.client on Spark集群

2.cluster on Spark集群

3.client on Yarn集群

4.cluster on Yarn集群

四、RDD的基本介绍

1.什么是RDD

2.RDD的五大特性

3.RDD的五大特点

五、如何构建RDD

六、RDD分区数量如何确定



一、Spark On Yarn两种部署方式

        当我们通过spark-submit方式来提交Spark应用到Yarn或者Spark集群的时候, 提供了两种部署模式: client 和 cluster。client模式 和 cluster模式本质区别: 【Driver程序运行的地方不同】

Client模式: 【Driver运行在提交应用程序的节点】,应用是在哪里进行提交的,Driver就会运行在哪里。默认值
    优势: 测试比较方便,直接通过Driver看到最终返回的结果
    弊端: 由于不是在一起的(Driver 和 executor不是在一个环境中),受网络影响因素会比较大,导致执行效率比较低
    使用: 【一般用于开发和测试】

Cluster模式: 【Driver运行在集群中某个Worker从节点中】
    优势: 提升Driver程序和executor程序之间的传输效率,从而提升整体的运行效率
    弊端: 由于Driver运行在集群里面,导致我们无法直接看到运行的结果,如果想要看到结果,就必须查看运行的日志
    使用: 【推荐在生产环境使用】

二、spark-submit命令

        后续需要将自己编写的Spark程序提交到相关的资源平台上,比如说: local yarn spark集群

Spark为了方便任务的提交操作,专门提供了一个用于进行任务提交的脚本文件: spark-submit

spark-submit在提交的过程中,设置非常多参数,调整任务相关信息。如果忘记了,可以使用spark-submit --help进行查看

  • 基本参数设置

  • Driver的资源配置参数

  • executor的资源配置参数

三、PySpark程序与Spark交互流程

1.client on Spark集群

1-在哪个节点上提交应用,就会在哪个节点上【启动Driver程序】

2-执行main函数,首先会创建SparkContext对象。底层是【基于PY4J】,根据python的构建方式,映射为Java代码

3-Driver程序连接到Spark集群的主节点Master。申请资源,用于启动Executor

4-Master主节点接收到资源申请,根据资源配置,分配资源。底层分配方案是【FIFO】。将分配方案返回给Driver程序
     executor1:node1 2个cpu,2GB
     executor2:node3 2个cpu,2GB
     
5-Driver程序连接到对应的Worker节点,占用相应资源,通知Worker启动Executor。启动以后,会反向注册回Driver程序

6-Driver开始处理代码 
  6-1 Driver加载RDD相关的算子(API/函数/方法),根据算子间的依赖关系,绘制【DAG有向无环图和划分Stage阶段】,并且确定每个阶段要多少个线程,每个线程要分配给哪个Executor来执行。(任务分配) 
  6-2 Driver程序通知对应的Executor来执行具体任务 
  6-3 Executor接收到任务之后,开始执行。RDD的代码中,有大量的Python函数,Executor是JVM程序,无法执行Python函数。因此会【调用Python解释器】,得到返回结果,并且将结果返回给Executor 
  6-4 Executor在运行过程中,判断是否要将结果返回给Driver程序。如果需要,就直接返回;如果不需要,就直接输出,结束即可 
  6-5 Driver程序监控Executor的任务执行状态,如果所有的Executor都执行完成,那么就认为任务运行完成

7-任务运行完后,Driver执行【sc.stop()】代码,通知Master。Master释放资源,Driver程序退出

2.cluster on Spark集群

区别点 : 【Driver程序就不是运行在提交程序的节点上了,而是在Spark集群中随机找一个从节点Worker启动Driver程序】

1-程序提交到Spark集群的主节点Master
2-主节点Master接收到任务之后,会根据Driver资源配置,在集群中随机选择某个从节点,占用相应资源,启动Driver程序
3-Driver程序执行main函数,首先会创建SparkContext对象。底层是基于PY4J,根据python的构建方式,映射为Java代码。创建成功后,会注册到Master主节点

4-Driver程序连接到Spark集群的主节点。申请资源,用于启动Executor

5-Master主节点接收到资源申请,根据资源配置,分配资源。底层分配方案是FIFO先进先出。将分配方案返回给Driver程序
     executor1:node1 2个cpu,2GB
     executor2:node3 2个cpu,2GB
     
6-Driver程序连接到对应的Worker节点,占用相应资源,通知Worker启动Executor。启动以后,会反向注册回Driver程序

7-Driver开始处理代码 
  7-1 Driver加载RDD相关的算子(API/函数),根据算子间的依赖关系,绘制DAG执行流程图和划分Stage阶段,并且确定每个阶段要多少个线程,每个线程要分配给哪个Executor来执行。(任务分配) 
  7-2 Driver程序通知对应的Executor来执行具体任务 
  7-3 Executor接收到任务之后,开始执行。RDD的代码中,有大量的Python函数,Executor是JVM程序,无法执行Python函数。因此会【调用Python解释器】,得到返回结果,并且将结果返回给Executor 
  7-4 Executor在运行过程中,判断是否要将结果返回给Driver程序。如果需要,就直接返回;如果不需要,就直接输出,结束即可 
  7-5 Driver程序监控Executor的任务执行状态,如果所有的Executor都执行完成,那么就认为任务运行完成

8-任务运行完后,Driver执行sc.stop()代码,通知Master。Master释放资源,Driver程序退出

处使用的url网络请求的数据。

3.client on Yarn集群

区别点: 【Driver将资源申请的工作移交给了ApplicationMaster来负责,Driver只负责任务分配、任务管理等工作】

1- 首先会在提交的的节点上启动一个Driver程序
2- Driver启动后,执行mian函数,首先创建SparkContext对象(底层是基于PY4J,识别python的构建方式, 将其映射为Java代码)

3- 连接Yarn集群的主节点ResourceManager,将需要申请的资源封装成一个任务,提交给Yarn的主节点ResourceManager。主节点ResourceManager收到任务后,首先随机的选择一个nodemanager启动ApplicationMaster

4- 当ApplicationMaster启动后,会和yarn的主节点建立心跳机制,告知已经启动成功了。启动成功后,就进行资源的申请工作,将需要申请的资源通过心跳包的形式发送给ResourceManager。ResourceManager收到资源申请后,开始进行资源分配工作,底层是基于资源调度器来实现(默认为Capacity容量调度)。当ResourceManager将资源分配OK后,等待ApplicationMaster进拉取操作。ApplicationMaster会定时的通过心跳的方式询问ResourceManager是否已经准备好资源,一旦发现准备好,立即拉取对应资源信息

5- ApplicationMaster根据获取到的资源信息连接对应的节点,通知对应nodemanager启动executor,并占用相应资源,nodemanage对应executor启动完成后,反向注册回给Driver程序(已经启动完成)

6- Driver开始处理代码:      
    6.1 首先会加载所有的RDD相关的API(算子),基于算子之间的依赖关系,形成DAG执行流程图,划分stage阶段,并且确定每个阶段应该运行多少个线程以及每个线程应该交给哪个executor来运行(任务分配)     
    6.2 Driver程序通知对应的executor程序,来执行具体的任务     
    6.3 Executor接收到任务信息后,启动线程,开始执行处理即可。executor在执行的时候,由于RDD代码中有大量的Python的函数,Executor是一个JVM程序,无法解析Python函数,此时会调用Python解析器,执行函数, 并将函数结果返回给Executor 
    6.4 Executor在运行过程中,如果发现最终的结果需要返回给Driver,直接返回Driver,如果不需要返回, 直接输出 结束即可     
    6.5 Driver程序监听这个executor执行的状态信息,当Executor都执行完成后,Driver认为任务运行完成了,同时ApplicationMaster也会接收到各个节点执行完成状态,然后通知ResourceManager。任务执行完成,ResourceManager回收资源,关闭ApplicationMaster,并通知Driver程序

7-  Driver执行sc.stop(),Driver程序退出即可

4.cluster on Yarn集群

区别点: 【Driver和ApplicationMaster合二为一,ApplicationMaster就是Driver,Driver就是ApplicationMaster】

1- 首先会将任务提交给Yarn集群的主节点(ResourceManager)
2- ResourceManager接收到任务信息后,根据Driver(ApplicationMaster)的资源配置信息要求,选择一个nodeManager节点(有资源的,如果都有随机)来启动Driver(ApplicationMaster)程序,并且占用相对应资源
3- Driver(ApplicationMaster)启动后,执行main函数。首先创建SparkContext对象(底层是基于PY4J,识别python的构建方式,将其映射为Java代码)。创建成功后,会向ResourceManager进行建立心跳机制,告知已经启动成功了

4- 根据executor的资源配置要求,向ResourceManager通过心跳的方式申请资源,用于启动executor(提交的任务的时候,可以自定义资源信息)

5- ResourceManager接收到资源申请后,根据申请要求,进行分配资源。底层是基于资源调度器来资源分配(默认为Capacity容量调度)。然后将分配好的资源准备好,等待Driver(ApplicationMaster)拉取操作        
      executor1: node1  2个CPU 2GB内存        
      executor2: node3  2个CPU 2GB内存

6- Driver(ApplicationMaster)会定时询问是否准备好资源,一旦准备好,立即获取。根据资源信息连接对应的节点,通知nodeManager启动executor,并占用相应资源。nodeManager对应的executor启动完成后,反向注册回给Driver(ApplicationMaster)程序(已经启动完成)

7- Driver(ApplicationMaster)开始处理代码:      
    7.1 首先会加载所有的RDD相关的API(算子),基于算子之间的依赖关系,形成DAG执行流程图,划分stage阶段,并且确定每个阶段应该运行多少个线程以及每个线程应该交给哪个executor来运行(任务分配)     
    7.2 Driver(ApplicationMaster)程序通知对应的executor程序, 来执行具体的任务     
    7.3 Executor接收到任务信息后, 启动线程, 开始执行处理即可: executor在执行的时候, 由于RDD代码中有大量的Python的函数,Executor是一个JVM程序 ,无法解析Python函数, 此时会调用Python解析器,执行函数, 并将函数结果返回给Executor 
    7.4 Executor在运行过程中,如果发现最终的结果需要返回给Driver(ApplicationMaster),直接返回Driver(ApplicationMaster),如果不需要返回,直接输出 结束即可     
    7.5 Driver(ApplicationMaster)程序监听这个executor执行的状态信息,当Executor都执行完成后,Driver(ApplicationMaster)认为任务运行完成了

8- 当任务执行完成后,Driver执行sc.stop()通知ResourceManager执行完成,ResourceManager回收资源,Driver程序退出即可

四、RDD的基本介绍

1.什么是RDD

RDD:英文全称Resilient Distributed Dataset,叫做弹性分布式数据集,是Spark中最基本的数据抽象,代表一个不可变、可分区、里面的元素可并行计算的集合。

  • Resilient弹性:【RDD的数据可以保存到内存或者磁盘】

  • Distributed分布式:【RDD的数据可以分布式存储在集群中的节点,用于分布式计算】

  • Dataset数据集:【一个用于存放数据的集合】

2.RDD的五大特性

1、RDD是有一系列分区组成的
2、对RDD做计算,相当于对RDD的每个split或分区做计算
3、RDD之间存在着依赖关系,宽依赖和窄依赖
4、对于KV类型的RDD,我们可以进行自定义分区方案
5、移动数据不如移动计算,让计算程序离数据越近越好

3.RDD的五大特点

1、分区:RDD逻辑上是分区的,仅仅是定义分区的规则,并不是直接对数据进行分区操作,因为RDD本身不存储数据。
2、只读:RDD是只读的,要想改变RDD中的数据,只能在现有的RDD基础上创建新的RDD。
3、依赖:RDD之间存在着依赖关系,宽依赖和窄依赖
4、缓存:如果在应用程序中多次使用同一个RDD,可以将该RDD缓存起来,该RDD只有在第一次计算的时候会根据血缘关系得到分区的数据
5、checkpoint:与缓存类似的,都是可以将中间某一个RDD的结果保存起来,只不过checkpoint支持持久化保存

五、如何构建RDD

构建RDD对象的方式主要有两种:

1、通过 textFile(data): 通过读取外部文件的方式来初始化RDD对象,实际工作中经常使用。
2、通过 parallelize(data): 通过自定义列表的方式初始化RDD对象。(一般用于测试)

六、RDD分区数量如何确定

1- RDD分区数量(线程数量)一般设置为【CPU核数的2-3倍】

2- RDD的分区数量取决于多个因素: 调用任务时候设置CPU核数、对应API设置分区数量,以及本身读取文件的分区数等等因素

3- 当初始化SparkContext的时候, 其实我们确定了一个基本的并行度参数【spark.default.parallelism】,默认为CPU核数。如果是集群,至少为2;如果local模式,取决于local[N] N为多少,并行度就是多少,即分区数就是多少

4- 通过parallelize来构建RDD: 如果没有指定分区数,那么分区数量取决spark.default.parallelism;如果设置了分区数量,取决于设置的分区数

5- 通过textFile(path,minPartition)来构建RDD: 
    5-1 首先取决于defaultMinPartition的值。如果没有指定minPartition,defaultMinPartition等于min(spark.default.parallelism,2);如果指定了minPartition,defaultMinPartition等于minPartition
    5-2 读取本地文件: 【RDD分区数=max(本地文件分片数,defaultMinPartition)】
    5-3 读取HDFS文件: 【RDD分区数=max(文件的block块,defaultMinPartition)】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值