20210117

大数据 | 大数据基础--系统之大数据批处理框架--Spark

亲爱的读者朋友大家晚上好,上次我们介绍了Hadoop的数据管理系统,并且我也提到从这次开始要介绍一些特殊的处理框架,在这篇文章中我们来看大数据的批处理框架Spark&Hyracks以及一些其它的批处理框架~

什么是大数据的批处理

  • 批处理操作大容量静态数据集,并在计算过程完成后返回结果。
  • 批处理模式中使用的数据集通常符合下列特征:
    • 有界:批处理数据集代表数据的有限集合。
    • 持久:数据通常始终存储在某种类型的持久存储位置中。
    • 大量:批处理操作通常是处理极为海量数据集的唯一方法。
  • 批处理适合
    • 需要访问全套记录才能完成的计算工作
    • 对历史数据进行分析
  • 批处理不适合
    • 对处理时间要求较高的场合

Spark的目标

  • 为集群运算提供分布式内存抽象,以支持具有工作集的应用程序
  • 保留了MapReduce的优秀特性
    • 容错机制(为崩溃程序和落后程序)
    • 数据局部性
    • 可扩展性

解决方案:使用“弹性分布式数据集”(RDDs)的增强数据流模型

Spark与Hadoop的对比

先来看一下MapReduce的执行流程1610865767727

再来看一下Spark的执行流程,相比于MapReduce的执行流程,主要是多了数据的存储过程1610865795461

大数据的批处理任务的抽象(Spark-RDD)

需要解决的问题

  • 操作的数据形式和结构是什么?
  • 应用程序可以对于数据做何种操作?

需要考虑的问题

  • 适用的场景/数据是什么?
  • 面向的软硬件环境是什么?
  • 支撑应用程序之间的界面在哪里?

RDD设计背景

  • 许多迭代式(比如机器学习、图算法等)和交互式数据挖掘 工具,共同之处是,不同计算阶段之间会重用中间结果
  • 目前的MapReduce框架都是把中间结果写入到稳定存储(比如磁盘)中,带来了大量的数据复制、磁盘IO和序列化开销
  • RDD提供了一个抽象的数据架构,不必担心底层数据的分布式特性,只需将具体的应用逻辑表达为一系列转换处理
  • 不同RDD之间的转换操作形成依赖关系,可以实现数据流水 处理,避免中间数据存储

RDD概念

  • 一个RDD是一个分布式对象集合,本质上是一个只读的分 区记录集合
  • 每个RDD可分成多个分区,每个分区就是一个数据集片段
  • 一个RDD的不同分区可以被保存到集群中不同的节点上, 从而可以在集群中的不同节点上进行并行计算
  • RDD提供了一种高度受限的共享内存模型
    • RDD是只读的记录分区的集合,不能直接修改
    • 只能基于稳定的物理存储中的数据集创建RDD,或者通过在其他RDD上执行确定的转换操作(如map、join和 group by)而创建得到新的RDD

RDD操作

  • RDD提供了一组丰富的操作以支持常见的数据运算,分为 “动作”(Action)和“转换”(Transformation)两种类型
  • RDD提供的转换接口都非常简单,都是类似map、filter、 groupBy、join等粗粒度的数据转换操作,而不是针对某个数 据项的细粒度修改(不适合网页爬虫)
  • RDD已经被实践证明可以高效地表达许多框架的编程模型(如MapReduce、SQL、Pregel)
  • Spark用Scala语言实现了RDD的API,程序员可以通过调用 API实现对RDD的各种操作

RDD执行过程

  • RDD读入外部数据源进行创建
  • RDD经过一系列的转换(Transformation)操作,每一次都会产生不同的RDD,供给下一个转换操作使用
  • 最后一个RDD经过“动作”操作进行转换,并输出到外部数据源

RDD的高效的原因

  • 高效的容错性
    • 现有容错机制:数据复制或者记录日志
    • RDD:血缘关系、重新计算丢失分区、无需回滚系统、 重算过程在不同节点之间并行、只记录粗粒度的操作
  • 中间结果持久化到内存,数据在内存中的多个RDD操作之间进行传递,避免了不必要的读写磁盘开销
  • 存放的数据可以是Java对象,避免了不必要的对象序列化和反序列化

大数据的批处理框架的API

需要解决的问题

  • 程序员如何基于框架编写应用程序?

需要考虑的问题

  • 面向什么样的程序员?
  • 开发的效率?
  • 程序的易读性?
  • 程序的美感?
  • 是否符合传统开发的习惯?

Spark编程模型

1610867097985

操作RDD的API--程序员可以执行3种类型的操作

1610867166331

大数据的批处理系统的系统架构

需要解决的问题

  • 系统有哪些模块?
  • 模块之间如何交互?

需要考虑的问题

  • 有效配合硬件
  • 扩展性高
  • 效率高
  • 弹性好
  • 开发容易
  • 维护方便
  • 升级简单

基本概念

  • DAG:是Directed Acyclic Graph(有向无环图)的简称, 反映RDD之间的依赖关系
  • Executor:是运行在工作节点(WorkerNode)的一个进程 ,负责运行Task
  • 应用(Application):用户编写的Spark应用程序
  • 任务( Task ):运行在Executor上的工作单元
  • 作业( Job ):一个作业包含多个RDD及作用于相应RDD上 的各种操作
  • 阶段( Stage ):是作业的基本调度单位,一个作业会分为 多组任务,每组任务被称为阶段,或者也被称为任务集合, 代表了一组关联的、相互之间没有Shuffle依赖关系的任务组成的任务集

架构设计

  • Spark运行架构包括集群资源管理器(Cluster Manager)、运行 作业任务的工作节点(Worker Node)、每个应用的任务控制节 点(Driver)和每个工作节点上负责具体任务的执行进程 (Executor)
  • 资源管理器可以自带或Mesos或YARN1610867691742
  • SparkContext处于DriverProgram核心位置,所有与 Cluster、Worker Node交互的操作都需要SparkContext 来完成,相当于交互的代理
  • 一个应用由一个Driver和若干个作业构成,一个作业由多个阶段构成,一个阶段由 多个没有Shuffle关系的任务组成
  • 当执行一个应用时,Driver会向集群管理器申请资源,启动Executor,并向 Executor发送应用程序代码和文件,然后在Executor上执行任务,运行结束后,执行结果会返回给Driver,或者写到HDFS或者其他数据库中1610867765297

大数据的批处理系统的基本数据操作

需要解决的问题

  • 包括哪些基本数据操作?
  • 并行还是串行实现?
  • 高效实现算法?

需要考虑的问题

  • 有效支撑API
  • 容易理解
  • 扩展性高
  • 效率高

shuffle操作

1610867979831

宽窄依赖

  • 窄依赖 : 一个父RDD的分区对应 于一个子RDD的分区或多个父RDD的分区对应于一个子RDD 的分区
  • 宽依赖 : 存在一个父RDD的一个 分区对应一个子 RDD的多个分区
1610868064739

大数据的批处理系统中的流程生成

需要解决的问题

  • 基本数据操作和用户自定义逻辑的步骤划分
  • 基本数据操作和用户自定义逻辑的执行顺序

需要考虑的问题

  • 可用性高
  • 效率高
  • 容易理解
  • 容易支持调试工具

阶段划分

  • 根据DAG 图中的RDD 依赖关系,把一个作业分成多个阶段。
  • 阶段划分的依据是窄依赖和宽依赖:窄依赖对于作业的优化很有利,宽依赖无法优化
  • 逻辑上,每个RDD 操作都是一个fork/join(一种用于并行执行任务的框架),把计算fork 到每个RDD 分区,完成计算后对各个分区得到的结果进行join 操作,然后fork/join下一个RDD操作

宽依赖往往对应着shuffle操作(多对一,汇总,多节点),需要在运行过程中将同一个父RDD 的分区传入到不同的子RDD分区中,中间可能涉及多个节点之间的数据传输;而窄依赖 的每个父RDD的分区只会传入到一个子RDD分区中,通常可以在一个节点内完成转换。1610868393392

具体的划分方法如下所示

  • 通过分析各个RDD的依赖关系生成了DAG,再通过分析各个RDD 中的分区之间的依赖关系来决定如何划分Stage
  • 具体步骤(贪心法):
    • 在DAG中进行反向解析,遇到宽依赖就断开
    • 遇到窄依赖就把当前的RDD加入到Stage中
    • 将窄依赖尽量划分在同一个Stage中,可以实现流水线计算

大数据的批处理系统中的流程调度

需要解决的问题

  • 执行过程中如何执行操作?

需要考虑的问题

  • 可扩展性高
  • 效率高

Spark端到端流程

1610869009819
  • Spark 的Driver Program (简称 Driver)包含用户的应用程序
  • Driver完成task的解析和生成
  • Driver向Cluster Manager(集群资源管理器)申请运行task 需要的资源。
  • 集群资源管理器 为task分配满足 要求的节点,并在节点按照要求 创建Executor
  • 创建的Executor 向Driver注册。
  • Driver将spark应用程序的代码和文件传送给分配的executor
  • executor运行task,运行完之 后将结果返回给 Driver或者写入HDFS或其他介质。

RDD运行过程

  • 创建RDD对象
  • SparkContext负责计算RDD之间的依赖关系,构建DAG
  • DAGScheduler负责把DAG图分解成多个Stage,每个Stage中包含了多个 Task,每个Task会被TaskScheduler分发给各个WorkerNode上的Executor去执行

大数据的批处理系统中的事务处理

需要解决的问题

  • 如何保证执行的正确性

需要考虑的问题

  • 结点出错怎么办?
  • 分布式系统出现读脏写脏怎么办?

RDD容错机制

  • RDD维护着可以用来重建丢失分区的信息

大数据的批处理系统中的数据存储机制

需要解决的问题

  • 何时存储数据?
  • 数据存储成什么形式?

需要考虑的问题

  • 高(时间/存储)效率
  • 内存满足要求

Spark中的存储机制

  • RDD缓存:包括基于内存和磁盘的缓存
    • 分区和数据块是一一对应的
    • 在内部建立RDD分区和数据块之间的映射,需要读取缓存的RDD时,根据映射关系取得分区对应的数据块
    • 内存缓存=哈希表+存取策略
    • 一个数据块对应着文件系统中的一个文件,文件名和块名称的映射关系是通过哈希算法计算所得的
  • Shuffle数据的持久化
    • Shuffle数据块必须是在磁盘上进行缓存的
    • Shuffle数据块的存储有两种方式:
      • 将Shuffle数据块映射成文件
      • 将Shuffle数据块映射成文件中的一段

总结

批处理框架其实还有很多,这次介绍的spark只是其中一个,下次我们来介绍另一个批处理框架hyracks~