Spark2.1.1<Spark架构综述>

内容来自书籍《Spark技术内幕:深入解析Spark内核架构设计与原理》

spark架构如下图所示:
这里写图片描述

Driver是用户编写的数据处理逻辑,这个逻辑中包含用户创建的SparkContext。SparkContext是用户逻辑与Spark集群主要的交互接口,它会和Cluster Manager交互,包括向它申请计算资源等。Cluster Manager负责集群的资源管理和调度,现在支持Standalone、Apache Mesos和Hadoop的YARN。Worker Node是集群中可以执行计算任务的节点。Executor是在一个Worker Node上为某应用启动的一个进程,该进程负责运行任务,并且负责将数据存在内存或者磁盘上。Task是被送到某个Executor上的计算单元。每个应用都有各自独立的Executor,计算最终在计算节点的Executor中执行。

用户程序从最开始的提交到最终的计算执行,需要经历以下几个阶段:

1)用户程序创建SparkContext时,新创建的SparkContext实例会连接到Cluster Manager。
Cluster Manager会根据用户提交时设置的CPU和内存等信息为本次提交分配计算资源,启动Executor。
2)Driver会将用户程序划分为不同的执行阶段,每个执行阶段由一组完全相同的Task组成,这些Task分别作用于待处理数据的不同分区。在阶段划分完成和Task创建后,Driver会向Executor发送Task。

3)Executor在接收到Task后,会下载Task的运行时依赖,在准备好Task的执行环境后,会开始执行Task,并且将Task的运行状态汇报给Driver。

4)Driver会根据收到的Task的运行状态来处理不同的状态更新。Task分为两种:一种是Shuffle Map Task,它实现数据的重新洗牌,洗牌的结果保存到Executor所在节点的文件系统中;另外一种是Result Task,它负责生成结果数据。

5)Driver会不断地调用Task,将Task发送到Executor执行,在所有的Task都正确执行或者超过执行次数的限制仍然没有执行成功时停止。

RDD(弹性分布式数据集)

RDD是只读的、分区记录的集合。RDD只能基于在稳定物理存储中的数据集和其他已有的RDD上执行确定性操作来创建。这些确定性操作称为转换,如map、filter、groupBy、join。RDD不需要物化。RDD含有如何从其他RDD衍生(即计算)出本RDD的相关信息(即Lineage),Lineage),因此在RDD部分分区数据丢失的时候可以从物理存储的数据计算出相应的RDD分区。
每个RDD有5个主要的属性:
1)partition list,即数据集的基本组成单位。对于RDD来说,每个partition 都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的partition 个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。
2)一个计算每个partition 的函数。Spark中RDD的计算是以partition 为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。
3)RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。
4)一个Partitioner,即RDD的分区函数。当前Spark中实现了两种类型的分区函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。
5)一个列表,存储存取每个Partition的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。对每一个split计算的优先位置 Preferred Location。比如对一个hdfs文件进行计算时,可以获取优先计算的block locations

以上五个特征中包含四个函数和一个属性,如下所示:

protected def getPartitions: Array[Partition]     //only called once
def compute(split: Partition, context: TaskContext): Iterator[T]
protected def getDependencies: Seq[Dependency[_]] = dips    //only called once
protected def getPreferredLocations(split: Partition): Seq[String] = Nil
@transient val partitioner: Option[Partitioner] = None
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>untitled</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>first</module> <module>spring5-ioc-xml</module> <module>spring5-ioc-annotation</module> <module>spring5-reflect</module> <module>atguigu-spring</module> <module>spring6-aop</module> <module>spring6-jdbc-tx</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifa
最新发布
04-03
<think>好的,用户想了解如何在Maven的POM文件中配置Spring项目的依赖管理。首先,我需要回忆Maven中的dependencyManagement的作用。根据引用[2],dependencyManagement用于统一管理依赖版本和范围,子模块继承时可以不用指定版本号。而引用[3]提到可以通过<scope>import</scope>来聚合多个pom的dependencyManagement,这可能在Spring Boot项目中用到。 接下来,用户需要具体的例子,可能需要展示一个典型的Spring Boot项目的父POM配置。通常Spring Boot项目会使用spring-boot-starter-parent作为父项目,或者通过dependencyManagement引入Spring Boot的BOM(Bill of Materials)。比如,在父POM的dependencyManagement中导入spring-boot-dependencies,这样所有子模块的Spring依赖就可以省略版本号。 然后,用户可能想知道如何管理不同模块的依赖,比如web、data-jpa等。需要展示如何在子模块的dependencies中添加starter依赖,比如spring-boot-starter-web,并说明由于父POM的dependencyManagement,这里不需要写版本。 另外,引用[1]提到dependencies标签用于管理依赖,而dependencyManagement是集中管理版本。需要区分两者的不同,确保用户理解何时使用哪个部分。 还要注意是否需要处理多模块项目,引用[3]提到的聚合工程可能需要使用import scope来合并多个依赖管理,这在复杂项目中可能会有用。例如,如果项目同时需要Spring Cloud的依赖管理,可以通过import scope引入。 最后,确保提供的示例代码正确,符合Maven语法,并且注释清晰。同时,生成的相关问题需要涵盖用户可能进一步询问的内容,比如版本冲突解决、多模块配置等。</think>### Maven项目配置及Spring依赖管理示例 在Maven中管理Spring依赖时,通常结合`<dependencyManagement>`实现版本统一控制。以下是典型配置步骤: --- #### 1. **父POM中定义Spring Boot依赖管理** 通过`<dependencyManagement>`导入Spring Boot官方提供的BOM(Bill of Materials),自动管理所有Spring Boot相关依赖的版本: ```xml <project> <dependencyManagement> <dependencies> <!-- 引入Spring Boot官方BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project> ``` - `<scope>import</scope>`表示继承目标POM中定义的依赖管理规则[^3] - 子模块中引用Spring依赖时**无需指定版本号** --- #### 2. **子模块添加具体依赖** 在需要Spring功能的模块中,直接声明starter依赖: ```xml <dependencies> <!-- Web模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 数据访问模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> ``` --- #### 3. **多模块依赖管理(可选)** 对于需要合并多个BOM的复杂项目: ```xml <dependencyManagement> <dependencies> <!-- 同时引入Spring Cloud和Spring Boot的BOM --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2022.0.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` - 多个BOM的依赖版本会根据声明顺序合并 --- #### 4. **依赖范围控制示例** 通过`<scope>`定义依赖作用域: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` - `test`表示该依赖仅在测试阶段有效[^2] --- ### 关键概念对比 | 配置项 | 作用域 | 特点 | |---------------------|----------------|----------------------------------------------------------------------| | `<dependencies>` | 当前模块 | 直接引入依赖,版本号必须显式声明 | | `<dependencyManagement>` | 全局管理 | 仅定义版本和范围,子模块引用时可省略版本号[^2] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值