当前位置: > > > Spark - 基础概念及工作原理梳理(应用场景、架构、模块、Hadoop对比)

Spark - 基础概念及工作原理梳理(应用场景、架构、模块、Hadoop对比)

一、Spark 概述

1,Spark 的定义

Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。

2,Spark 的应用场景

(1)批处理领域
    Spark 在批处理领域具有广泛的应用,可以处理大规模的离线数据分析和处理任务。以下是一些典型的应用场景和样例:
  • 数据清洗和转换:批处理数据常常需要进行清洗和转换,以便进行后续的分析。Spark 提供了强大的数据转换和操作功能,例如使用 Spark SQL 进行数据筛选、过滤和聚合,使用 Spark Core 进行复杂的数据转换和处理。
  • 日志分析:许多应用和系统会生成大量的日志数据,通过使用 Spark 进行批处理分析,可以从日志中提取有价值的信息。例如,可以使用 Spark SQL 对日志进行查询和聚合,从中获取关键指标和异常模式。
  • 批量推荐系统:基于用户行为数据和商品信息,构建批量推荐系统是一个常见的应用场景。Spark 提供了丰富的机器学习算法和工具,可以用于构建推荐模型,并在大规模数据集上进行批量推荐。

(2)实时流处理领域
    随着大数据和实时数据的兴起,实时流处理成为了许多应用场景的需求。Spark Streaming Spark 提供的处理实时数据流的模块,以下是一些实践案例:
  • 实时日志分析:许多应用和系统需要对实时生成的日志数据进行实时分析,以监控系统状态、检测异常和实时反馈。通过使用 Spark Streaming,可以对数据流进行实时处理和聚合,并生成实时的指标和报警。
  • 实时推荐系统:对于需要即时反馈的推荐系统,Spark Streaming 可以实时处理用户行为数据,快速更新推荐模型,并实时推送推荐结果给用户。
  • 实时欺诈检测:在金融领域,实时欺诈检测是一个关键的应用场景。Spark Streaming 可以对交易数据流进行实时处理和分析,及时发现潜在的欺诈行为,并采取相应的措施。

(3)机器学习领域
    Spark MLlib Spark 的机器学习库,提供了丰富的机器学习算法和工具,适用于大规模的机器学习任务。以下是一些应用示例:
  • 分类和回归Spark MLlib 提供了常见的分类和回归算法,如逻辑回归、决策树、随机森林等。这些算法可以对大规模数据集进行训练和预测,例如在广告点击率预测、用户购买行为预测等场景中。
  • 聚类和推荐Spark MLlib 支持聚类算法(如 K-means)和推荐算法(如协同过滤),可以用于对用户和商品进行聚类和推荐分析。这对于用户群体的细分和个性化推荐非常有价值。
  • 特征工程和数据预处理:在机器学习任务中,特征工程和数据预处理是非常重要的环节。Spark MLlib 提供了一系列特征转换和处理工具,如特征提取、特征选择、标准化等,可以用于对原始数据进行处理和准备,以供机器学习算法使用。
  • 模型评估和调优Spark MLlib 提供了丰富的评估指标和模型选择工具,可以用于评估训练模型的性能,并进行模型调优和参数优化。这对于提高模型的准确性和泛化能力非常重要。

3,Spark 的整体架构

    Spark 的整体架构采用了 Master-Worker 模式,其中包括一个主节点(Master)和多个工作节点(Worker)。主节点负责管理和协调工作节点,而工作节点负责执行具体的任务。
  • 主节点Master)是 Spark 集群的控制节点,负责管理任务调度、资源分配和监控任务的执行情况。它将 Spark 应用程序划分为不同的任务(Tasks)并将它们分发给工作节点执行。主节点还负责维护和管理整个集群的状态信息。
  • 工作节点Worker)是 Spark 集群中的工作进程,负责执行任务。每个工作节点都有自己的计算和存储资源,并在其上运行 Executor 来执行具体的任务。工作节点通过与主节点的通信来接收任务并上报任务执行的状态。

4,Spark 的核心模块

  • Spark Core:提供了 Spark 最基础与最核心的功能,提供分布式任务调度、内存管理和容错机制等功能。Spark 其他的功能如:Spark SQLSpark StreamingGraphX, MLlib 都是在 Spark Core 的基础上进行扩展的
  • Spark SQL:是 Spark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。
  • Spark Streaming:是 Spark 平台上针对实时数据进行流式计算的组件,提供了丰富的处理数据流的 API。 
  • Spark MLlib:是 Spark 提供的一个机器学习算法库。MLlib 不仅提供了模型评估、数据导入等额外的功能,还提供了一些更底层的机器学习原语。
  • Spark GraphX:是 Spark 面向图计算提供的框架与算法库。

5,关键术语

(1)Resilient Distributed DatasetRDD):RDD 叫做弹性分布式数据集,是 Spark 中最基本的数据处理模型。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。RDD 可以从磁盘上的数据集、内存中的数据结构或其他 RDD 转换而来,可以被分区和并行操作。
  • 弹性
    • 存储的弹性:内存与磁盘的自动切换;
    • 容错的弹性:数据丢失可以自动恢复;
    • 计算的弹性:计算出错重试机制;
    • 分片的弹性:可根据需要重新分片。
  • 分布式:数据存储在大数据集群不同节点上
  • 数据集RDD 封装了计算逻辑,并不保存数据
  • 数据抽象RDD 是一个抽象类,需要子类具体实现
  • 不可变RDD 封装了计算逻辑,是不可以改变的,想要改变,只能产生新的 RDD,在新的 RDD 里面封装计算逻辑
  • 可分区、并行计算

(2)Transformations(转换算子)和 Actions(行动算子):通过 TransformationsActions 的组合,可以构建复杂的计算流程,并实现灵活的数据处理和分析。
  • Transformations 是指应用于 RDD 的延迟计算操作,它们不会立即执行,而是记录在 RDD 的转换操作序列中。常见的 Transformations 包括 mapfilterreduceByKey 等。Transformations 是惰性执行的,只有当遇到 Action 时才会触发实际的计算。
  • Actions 是指对 RDD 执行实际计算并返回结果的操作,它们会触发 Spark 执行 RDD 上的 Transformations 并生成结果。常见的 Actions 包括 countcollectsaveAsTextFile 等。

(3)ShuffleShuffleSpark 中一个重要的概念,它指的是将数据重新分区和重组以进行后续计算的过程。Shuffle 通常发生在具有宽依赖(即依赖多个父 RDD 分区的子 RDD)的操作中,例如 groupByKeyreduceByKeyjoin 等。
  • Shuffle 过程中,Spark 将数据重新分区并重新组织,以确保具有相同键的数据被聚合到同一个分区中,从而为后续计算提供更高效的访问。Shuffle 过程涉及数据的排序、写入磁盘、网络传输和读取等操作,因此在性能和资源消耗方面需要特别关注。
  • Shuffle 操作对 Spark 应用程序的性能具有重要影响,因为它涉及大量的数据移动和网络传输。合理地管理和优化 Shuffle 操作对于提高 Spark 应用程序的性能和可扩展性非常重要。通过合理的分区策略、适当的缓存机制以及调整并行度和资源分配等方式,可以减少 Shuffle 的开销并提高应用程序的执行效率。

(4)DataFrameDataset:提供了更方便和高效的方式来处理结构化数据,使得数据科学家和开发人员能够更轻松地进行数据处理和分析。
  • DataFrame 是一种结构化的数据抽象,类似于关系型数据库中的表格,它具有命名的列和类型化的行。DataFrame 提供了更高级别的 API,支持 SQL 查询、数据过滤、聚合和操作。DataFrame 可以从多种数据源创建,如 CSV 文件、数据库表等。
  • DatasetDataFrame 的扩展,它是强类型的数据抽象,可以通过编译时类型检查提供更好的性能和类型安全性。Dataset 融合了 DataFrame 的结构化查询能力和 RDD 的强大功能,既可以进行高级的结构化查询,又可以进行复杂的函数式编程。

(5)Spark Driver Spark Executor:它们是 Spark 集群中的角色,之间通过网络进行通信和数据交换,协同工作以完成 Spark 应用程序的执行。Driver 将任务分发给 Executor,并将结果收集和合并,最终返回给应用程序。
  • Spark Driver Spark 应用程序的控制节点,负责将应用程序划分为不同的任务,并与集群中的 Executor 进行通信。Driver 负责调度和监控任务的执行,收集计算结果并返回给应用程序。
  • Spark Executor 是运行在集群节点上的工作进程,负责执行 Spark 应用程序的任务。每个 Executor 都会分配一部分数据和计算资源,并独立地执行任务。Executor 可以在集群的不同节点上并行执行,以提高计算效率。

(6)JobStageTask
  • Job 是以 Action 方法为界,遇到一个 Action 方法则触发一个 Job。在 Spark 中,一个 Job 是由一系列相互依赖的 RDD 转换和 Action 操作组成的逻辑单元。通常情况下,一个 Spark 应用程序由多个 Job 组成。每个 Job 代表了一次计算任务,它定义了要执行的计算逻辑以及相应的数据依赖关系。
  • StageJob 的子集,以 RDD 宽依赖(即 Shuffle)为界,遇到 Shuffle 做一次划分。一个 Job 通常包含了一个或多个 Stage。每个 Stage 代表了一组可以并行执行的任务,这些任务通过 Shuffle 操作将数据划分为不同的分区。Spark 会根据依赖关系将 Job 划分为多个 Stage,以便并行执行和优化计算。
  • TaskStage 的子集,以并行度(分区数)来衡量,分区数是多少,则有多少个 task。一个 Task 是作为 Job 的一部分被分配到集群中的 Executor 上执行的最小计算单元。每个 Task 负责处理一个 RDD 分区的数据,并执行相应的转换和操作。例如,对一个 RDD 执行 map 操作时,每个 Task 将负责处理 RDD 的一个分区,并将转换后的结果返回。一个 Job 可以包含多个 Task,这些 Task 在不同的 Executor 上并行执行,以实现高效的数据处理和计算。Spark 会根据数据分区和可用资源动态地将 Task 分配给 Executor,以实现负载均衡和优化计算性能。

6,Spark 的部署模式

(1)Spark 提供了多种部署模式,以满足不同的应用需求和环境配置。常见的部署模式有如下几种:
  • 本地模式Local Mode):该模式是最简单的 Spark 部署模式,适用于在单台机器上进行开发和测试。在本地模式下,Spark 应用程序以单线程的方式运行在本地机器上,无需启动集群或进行资源管理。这种模式非常适合小规模的数据集和快速迭代开发。
  • 独立模式Standalone Mode):该模式是 Spark 提供的一种分布式部署模式,可以在具有多台机器的集群上运行 Spark 应用程序。在独立模式下,用户需要手动配置和管理 Spark 集群的各个组件,包括主节点和工作节点。这种模式对于需要自定义配置和灵活性的场景非常适用,但也需要更多的管理和维护工作。
  • 集群模式Cluster Mode):该是 Spark 最常用的部署模式,也是生产环境中常见的部署方式。在集群模式下,Spark 应用程序在一个现有的集群管理框架(如 Apache MesosHadoop YARN)上运行。用户只需提交应用程序,由集群管理框架负责资源分配和任务调度。这种模式提供了高度的可扩展性和弹性,适用于大规模数据处理和生产环境部署。

(2)而针对集群模式,常见的 Spark 集群管理工具和平台有如下几个,它们简化了 Spark 集群的部署和管理,提供了便捷和可靠的集群管理功能。
  • Apache MesosMesos 是一种通用的集群管理框架,可以与 Spark 集成,用于管理 Spark 应用程序的资源分配和任务调度。
  • Hadoop YARNYARNYet Another Resource Negotiator)是 Apache Hadoop 生态系统的资源管理和调度框架,可以用于部署和管理 Spark 应用程序。
  • KubernetesK8S):Kubernetes 是一种开源的容器编排和管理平台,可以用于部署和管理 Spark 容器,提供灵活的资源调度和弹性扩展能力。
  • Amazon EMRAmazon EMRElastic MapReduce)是亚马逊 AWS 提供的一种托管式的 Spark 集群服务,简化了 Spark 集群的部署和管理。
  • DatabricksDatabricks 是一种基于 Spark 的托管式分析平台,提供了一整套 Spark 相关的服务和工具,包括集群管理、数据处理、机器学习 Google Cloud DataprocGoogle Cloud Dataproc Google Cloud 提供的一种托管式 SparkHadoop 服务,可以快速部署和管理 Spark 集群。
  • Microsoft Azure HDInsightAzure HDInsight Microsoft Azure 提供的一种托管式大数据分析服务,支持 Spark 和其他开源大数据技术,提供了简化的集群部署和管理功能。

7,Spark 通讯架构

(1)Spark 早期版本中采用 Akka 作为内部通信部件。而从 Spark2.x 系列起,Spark 抛弃 Akka,使用 Netty
Spark 使用 Netty 取代 Akka 原因Netty 内部高效的 Reactor 线程模型,无锁化的串行设计,高效的序列化,零拷贝,内存池等特性也保证了 Netty 不会存在性能问题。

(2)Spark 通信架构如下图所示:

 
  • RpcEndpoint:RPC 通信终端Spark 针对每个节点(Client/Master/Worker)都称之为一个 RPC 终端,且都实现 RpcEndpoint 接口,内部根据不同端点的需求,设计不同的消息和不同的业务处理,如果需要发送(询问)则调用 Dispatcher。在 Spark 中,所有的终端都存在生命周期:
    • Constructor -> onStart -> receive* -> onStop
  • RpcEnvRPC 上下文环境,每个 RPC 终端运行时依赖的上下文环境称为 RpcEnv;在当前 Spark 版本中使用的 NettyRpcEnv
  • Dispatcher消息调度(分发)器,针对于 RPC 终端需要发送远程消息或者从远程 RPC 接收到的消息,分发至对应的指令收件箱(发件箱)。如果指令接收方是自己则存入收件箱,如果指令接收方不是自己,则放入发件箱;
  • Inbox指令消息收件箱。一个本地 RpcEndpoint 对应一个收件箱,Dispatcher 在每次向 Inbox 存入消息时,都将对应 EndpointData 加入内部 ReceiverQueue 中,另外 Dispatcher 创建时会启动一个单独线程进行轮询 ReceiverQueue,进行收件箱消息消费;
  • RpcEndpointRefRpcEndpointRef 是对远程 RpcEndpoint 的一个引用。当我们需要向一个具体的 RpcEndpoint 发送消息时,一般我们需要获取到该 RpcEndpoint 的引用,然后通过该应用发送消息。
  • OutBox指令消息发件箱。对于当前 RpcEndpoint 来说,一个目标 RpcEndpoint 对应一个发件箱,如果向多个目标 RpcEndpoint 发送信息,则有多个 OutBox。当消息放入 Outbox 后,紧接着通过 TransportClient 将消息发送出去。消息放入发件箱以及发送过程是在同一个线程中进行;
  • RpcAddress表示远程的 RpcEndpointRef 的地址Host + Port
  • TransportClientNetty 通信客户端,一个 OutBox 对应一个 TransportClientTransportClient 不断轮询 OutBox,根据 OutBox 消息的 receiver 信息,请求对应的远程 TransportServer
  • TransportServerNetty 通信服务端,一个 RpcEndpoint 对应一个 TransportServer,接受远程消息后调用 Dispatcher 分发消息至对应收发件箱;

8,Spark 的任务调度

(1)Spark 的任务调度总体来说分两路进行,一路是 Stage 级的调度,一路是 Task 级的调度,总体调度流程如下图所示:

(2)Spark RDD 通过其 Transactions 操作,形成了 RDD 血缘(依赖)关系图,即 DAG,最后通过 Action 的调用,触发 Job 并调度执行,执行过程中会创建两个调度器:DAGSchedulerTaskScheduler
  • DAGScheduler 负责 Stage 级的调度,主要是将 job 切分成若干 Stages,并将每个 Stage 打包成 TaskSet 交给 TaskScheduler 调度。
  • TaskScheduler 负责 Task 级的调度,将 DAGScheduler 给过来的 TaskSet 按照指定的调度策略分发到 Executor 上执行,调度过程中 SchedulerBackend 负责提供可用资源,其中SchedulerBackend 有多种实现,分别对接不同的资源管理系统。

(3)Driver 初始化 SparkContext 过程中,会分别初始化 DAGSchedulerTaskSchedulerSchedulerBackend 以及 HeartbeatReceiver,并启动 SchedulerBackend 以及 HeartbeatReceiverSchedulerBackend 通过 ApplicationMaster 申请资源,并不断从 TaskScheduler 中拿到合适的 Task 分发到 Executor 执行。HeartbeatReceiver 负责接收 Executor 的心跳信息,监控 Executor 的存活状况,并通知到 TaskScheduler

附:Spark 与 Hadoop 对比

    HadoopMapReduce 是大家广为熟知的计算框架。而 Spark 出现的时间相对较晚,并且主要功能主要是用于数据计算,所以其实 Spark 一直被认为是 Hadoop 框架的升级版,也常被人们拿来比较。下面通过几个维度来比较二者的差别。

1,时间线对比

(1)Hadoop
  • 20061 月,Doug Cutting 加入 Yahoo,领导 Hadoop 的开发
  • 20081 月,Hadoop 成为 Apache 顶级项目
  • 2011 1.0 正式发布
  • 20123 月稳定版发布
  • 201310 月发布 2.X (Yarn)版本
(2)Spark
  • 2009 年,Spark 诞生于伯克利大学的 AMPLab 实验室
  • 2010 年,伯克利大学正式开源了 Spark 项目
  • 2013 6 月,Spark 成为了 Apache 基金会下的项目
  • 20142 月,Spark 以飞快的速度成为了 Apache 的顶级项目
  • 2015 年至今,Spark 变得愈发火爆,大量的国内公司开始重点部署或者使用 Spark

2,功能对比

(1)Hadoop
  • Hadoop 是由 java 语言编写的,在分布式服务器集群上存储海量数据并运行分布式分析应用的开源框架
  • 作为 Hadoop 分布式文件系统,HDFS 处于 Hadoop 生态圈的最下层,存储着所有的数据,支持着 Hadoop 的所有服务。它的理论基础源于 GoogleTheGoogleFileSystem 这篇论文,它是 GFS 的开源实现。
  • MapReduce 是一种编程模型,Hadoop 根据 GoogleMapReduce 论文将其实现,作为 Hadoop 的分布式计算模型,是 Hadoop 的核心。基于这个框架,分布式并行程序的编写变得异常简单。综合了 HDFS 的分布式存储和 MapReduce 的分布式计算,Hadoop 在处理海量数据时,性能横向扩展变得非常容易。
  • HBase 是对 GoogleBigtable 的开源实现,但又和 Bigtable 存在许多不同之处。HBase 是一个基于 HDFS 的分布式数据库,擅长实时地随机读/写超大规模数据集。它也是 Hadoop 非常重要的组件。
(2)Spark
  • Spark 是一种由 Scala 语言开发的快速、通用、可扩展的大数据分析引擎
  • Spark Core 中提供了 Spark 最基础与最核心的功能
  • Spark SQLSpark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。
  • Spark StreamingSpark 平台上针对实时数据进行流式计算的组件,提供了丰富的处理数据流的 API

3,优劣势对比

    Spark 和 Hadoop 的根本差异是多个作业之间的数据通信问题 : Spark 多个作业之间数据通信是基于内存,而 Hadoop 是基于磁盘。而这个差异也决定了它们在不同的场景下各有优势和不足。
(1)Spark 的优势
  • Hadoop MapReduce 由于其设计初衷并不是为了满足循环迭代式数据流处理,因此在多并行运行的数据可复用场景(如:机器学习、图挖掘算法、交互式数据挖掘算法)中存在诸多计算效率等问题。所以 Spark 应运而生,Spark 就是在传统的 MapReduce 计算框架的基础上,利用其计算过程的优化,从而大大加快了数据分析、挖掘的运行和读写速度,并将计算单元缩小到更适合并行计算和重复使用的 RDD 计算模型。
  • 机器学习中 ALS、凸优化梯度下降等。这些都需要基于数据集或者数据集的衍生数据反复查询反复操作。MR 这种模式不太合适,即使多 MR 串行处理,性能和时间也是一个问题。数据的共享依赖于磁盘。另外一种是交互式数据挖掘,MR 显然不擅长。而 Spark 所基于的 scala 语言恰恰擅长函数的处理。
  • Spark 是一个分布式数据快速分析项目。它的核心技术是弹性分布式数据集(Resilient Distributed Datasets),提供了比 MapReduce 丰富的模型,可以快速在内存中对数据集进行多次迭代,来支持复杂的数据挖掘算法和图形计算算法。
  • Spark Task 的启动时间快。Spark 采用 fork 线程的方式,而 Hadoop 采用创建新的进程的方式。
  • Spark 只有在 shuffle 的时候将数据写入磁盘,而 Hadoop 中多个 MR 作业之间的数据交互都要依赖于磁盘交互
  • Spark 的缓存机制比 HDFS 的缓存机制高效。

(2)Spark 的不足
  • 虽然在绝大多数的数据计算场景中,Spark 确实会比 MapReduce更有优势。但是 Spark 是基于内存的,所以在实际的生产环境中,由于内存的限制,可能会由于内存资源不够导致 Job 执行失败,此时,MapReduce 其实是一个更好的选择,所以 Spark 并不能完全替代  MR

4,Spark 可以取代 Hadoop 吗?

(1)Spark 要取代 Hadoop。其实这是一种错误的说法。
  • Spark 是一个基于内存的计算引擎,而 Hadoop 包含 HDFSMapReduceYARNSpark 的角色类 似于 Hadoop 中的 MapReduce
(2)那 Spark 是不是可以取代 MapReduce 呢?
  • 以目前企业中的实际应用来说,对于海量数据分析,使用 Spark 的场景居多,主要是因为:Spark 中提供了很多高阶函数,可以轻松实现复杂迭代计算,并且其支持内存计算,计算效率非常高。MapReduce 的使用场景就比较少了,但 MapReduce 的稳定性是 Spark 无法企及的。
  • 若数据量比较大,在使用 Spark 计算时,如果内存分配不合理,则会导致任务执行失败,无法计算出最终的结果。使用 MapReduce 计算虽然会慢一些,但肯定可以计算出最终的结果。所以,在特定的需求下 MapReduce 还是占有一席之地的。
  • 在实际工作中,Spark Hadoop 是深度结合在一起使用的,如下图所示。Spark 支持 ON YARN 模式,可以在 YARN 中运行,并且 Spark 任务的数据源和目的地都可以使用 HDFS。所以,Spark 的出现并不是为了取代 Hadoop,而是为了和 Hadoop 一起提高海量数据的计算效率。

评论0