|
|
51CTO旗下网站
|
|
移动端

Spark学习笔记:核心概念可视化

对于在分布式系统上背景知识较少的人来说,学习Spark并非易事。 即使我已经使用Spark已有一段时间了,但我发现全面了解Spark中的所有核心概念仍然很耗时。 Spark的官方文档提供了非常详细的解释,但更多地侧重于实际编程方面。

作者:闻数起舞来源:今日头条|2020-05-08 13:44

对于在分布式系统上背景知识较少的人来说,学习Spark并非易事。 即使我已经使用Spark已有一段时间了,但我发现全面了解Spark中的所有核心概念仍然很耗时。 Spark的官方文档提供了非常详细的解释,但更多地侧重于实际编程方面。 同样,大量的在线教程可能会让您不知所措。 因此,在本文中,我想以更直观的方式记下那些Spark核心概念。 希望您也会发现它有用!

注意:也许您已经对Hadoop有一定的了解,所以我将跳过对琐碎事物(例如节点和集群)的解释。

Spark架构和部署模式

简而言之,Spark在主工作架构上运行,这是并行任务计算模型的典型类型。 运行Spark时,我们可以选择几种模式,即本地(主,执行器,驱动程序都在同一台JVM机器中),独立,YARN和Mesos。 在这里,我们仅谈论YARN上的Spark以及YARN客户端和YARN群集之间的区别,因为两者都是最常用的,但非常令人困惑。

下两张图片说明了两种模式的设置。 它们看起来很相似,不是吗? 但是,通过查看橙色突出显示的部分,您可能会注意到细微的差别,这就是Spark驱动程序的位置。 这基本上是两种模式之间的唯一区别。

Spark学习笔记:核心概念可视化
Spark学习笔记:核心概念可视化
> Fig 1. Spark deployment mode YARN-client (left) and YARN-cluster (right)

假设您编写了一个名为spark_hello_world.py的Spark应用程序。 在客户端模式下,使用spark-submit执行python文件时,驱动程序直接在spark-submit进程内启动,因此它将与spark_hello_world.py驻留在同一台计算机上。 初始化Spark上下文时,本地计算机中的驱动程序将连接到群集中的应用程序主机。 从主机开始,Spark启动了更多执行器。

在群集模式下,spark_hello_world.py代码位于客户端计算机中,而客户端计算机不在群集中。 执行应用程序python代码时,它将在集群中的一个节点中启动驱动程序。 与Spark应用程序主文件一起,它可以启动执行程序并发布应用程序命令。

鉴于设置差别不大,您一定想知道为什么我们需要两种不同的模式。 在实践中,这与客户端计算机与工作计算机在物理上位于同一位置有关。 如果客户端计算机离工作节点"遥远",例如 您在笔记本电脑上编写了spark_hello_world.py,但是工作程序是AWS EC2实例,那么使用群集模式是有意义的,以便最大程度地减少驱动程序和执行程序之间的网络延迟。 在另一种情况下,如果您的python文件位于与工作节点"非常近"的网关计算机中,则客户端模式可能是一个不错的选择。

Spark学习笔记:核心概念可视化

执行者

现在,我们了解了Spark集群的设置,让我们放大到Spark中最重要的元素之一-执行器。 执行器是运行任务并将数据跨任务存储在内存或磁盘中的过程。

浏览Spark文档时,您可能会对与执行程序相关的可配置参数数量感到惊讶。 让我们从视觉上看一下它,而不是一次又一次地尝试弄清楚一个人的多个参数之间的关系。

Spark学习笔记:核心概念可视化
> Fig 2. Spark executor internals

如图2所示,在每个执行器中都有一个执行器JVM,用于存储RDD分区,缓存的RDD分区,运行内部线程和任务。 如果内核数量超出任务要求,则JVM中还将有可用的内核。 这个执行器JVM的绿色块将成为我们研究执行器中的内存管理的起点。

执行程序内存管理

在执行程序容器中,主要分配了两个内存块:内存开销和执行程序内存。

内存开销是为虚拟机开销,内部字符串,其他本机开销等内容预留的堆外内存。通过将数据缓存在主要Java堆空间之外但仍在RAM中的方式,堆外内存可使高速缓存克服冗长的时间 使用大堆大小时,JVM垃圾收集会暂停。

执行器的内存包括以下三个部分。

  • 预留内存
  • 用户内存:用于在Spark中存储用户数据结构和内部元数据等内容。
  • 存储和执行内存:用于存储所有RDD分区并为任务分配运行时内存。

图3显示了每个存储块的相关参数。 假设我们将spark.executor.memory设置为4 GB,那么Spark将向资源管理器请求总共4.4 GB的内存。 在4 GB的执行程序内存中,我们实际上获得了3.7 GB,因为其余部分已保留。 默认情况下,我们获得2.2 GB(0.6 * 3.7)作为执行+存储内存。 其中1.1 GB用于存储RDD等存储空间,其余空间用于执行内存。

Spark学习笔记:核心概念可视化
> Fig 3. Spark executor memory decomposition

RDD,工作,阶段和任务

如果您已经开始使用Spark UI调试Spark应用程序,那么可能很熟悉诸如作业,阶段和任务之类的关键字。 那么它们与RDD有何关系?

我们知道在RDD上有两种操作,即转换(例如,过滤,并集,非重复,交集),这些操作实际上是在没有实际执行的情况下从现有的RDD中生成一个新的RDD,以及要执行的操作(例如,采取,显示,收集,foreach) 触发执行。 转换RDD时,基于父RDD和转换后的RDD之间的关系,相关性可以窄或宽。 依赖关系较窄,在父RDD中,一个或多个分区将映射到新RDD中的一个分区。 尽管具有广泛的依赖性,例如在执行join或sortBy时,但我们需要对分区进行混洗以计算新的RDD。

Spark学习笔记:核心概念可视化
> Fig 4–1. narrow dependency in RDD transformation
Spark学习笔记:核心概念可视化
> Fig 4–2. Wide dependency in RDD transformation

因此,作业,阶段和任务由操作类型和转换类型确定。 在RDD上执行操作时,将创建一个作业。 在工作中,可能有多个阶段,具体取决于我们是否需要执行广泛的转换(即洗牌)。 在每个阶段中,可以将一个或多个转换映射到每个执行程序中的任务。

Spark学习笔记:核心概念可视化
> Fig 5. Illustration of one Spark job

为了真正理解它,我们来看以下简单的代码片段。

  1. val RDD1 = sc.parallelize(Array('1''2''3''4''5')).map{ x => val xi = x.toInt; (xi, xi+1) } 
  2. val RDD2 = sc.parallelize(Array('1''2''3''4''5')).map{ x => val xi = x.toInt; (xi, xi*10) } 
  3. val joinedData = RDD2.join(RDD1) 
  4. val filteredRDD = joinedData.filter{case (k, v) => k % 2 == 0} 
  5. val resultRDD = filteredRDD.mapPartitions{ iter => iter.map{ case (k, (v1, v2) ) => (k, v1+v2) } } 
  6. resultRDD.take(2) 

此代码中包含一些操作,即map,join,filter,mapPartitions和take。 创建RDD时,Spark将分别为RDD1和RDD2生成两个阶段,如阶段0和1所示。由于map函数包含一个狭窄的依赖性,因此映射的RDD也将分别包含在阶段0和1中。 然后,我们将RDD1和RDD2连接起来,因为连接是包含混洗的广泛转换,因此Spark为该操作创建了另一个阶段。 之后,filter和mapPartition仍然是第2阶段的狭窄转换,通过调用take(这是一个动作),我们触发了Spark的执行。

Spark学习笔记:核心概念可视化
> Fig 6. DAG visualization

因此,这就是Spark的所有基本内容。 希望在阅读本文之后,这些概念对您来说更加清楚。 学习愉快!

【编辑推荐】

  1. Spark 3.0 终于支持 event logs 滚动了
  2. 解决 Spark 数据倾斜的 8 大实用方法
  3. 三分钟读懂Hadoop、HBase、Hive、Spark分布式系统架构
  4. 为何Spark在编程界越来越吃香?Spark将成为数据科学家的统一平台
  5. Flink及Storm、Spark主流流框架比较,到底谁会更胜一筹?
【责任编辑:未丽燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

从头解锁Python运维

从头解锁Python运维

多维度详解
共19章 | 叱诧少帅

264人订阅学习

Active Directory 架构规划实战

Active Directory 架构规划实战

4类AD架构规划
共15章 | wx5918591c0084b

320人订阅学习

庖丁解牛Ceph分布式存储

庖丁解牛Ceph分布式存储

云计算存储的基石
共5章 | Happy云实验室

189人订阅学习

视频课程+更多

vsftpd服务配置与管理(CentOS7)-Linux服务配置系列课程第四章

vsftpd服务配置与管理(CentOS7)-Linux服务

讲师:曲广平1075人学习过

清华编程高手尹成带你基于算法实践java

清华编程高手尹成带你基于算法实践java

讲师:尹成5067人学习过

C语言

C语言

讲师:王健伟96305人学习过

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微