halcon实例实战第二版_Spark实战第二版(涵盖Spark3.0)第六章 部署应用程序

关注公众号:登峰大数据,阅读Spark实战第二版(完整中文版),系统学习Spark3.0大数据框架!

如果您觉得作者翻译的内容有帮助,请分享给更多人。您的分享,是作者翻译的动力!

9bfc2412f4000522b5a01ced2db33395.png

本章涵盖了
  • 部署一个Spark应用程序
  • 在Spark集群环境中定义关键组件的角色
  • 在集群上运行应用程序
  • 使用Spark计算近似的π值
  • 分析执行日志

在前几章中,了解了Apache Spark是什么以及如何构建简单的应用程序,并且理解了dataframe和惰性等关键概念。本章与上一章相关联:在第5章中构建了一个应用程序,将在本章中部署它。在此之前阅读第5章并不是必须的,但强烈建议。

在本章中,将把编写代码放在一边,探索在转向部署和生产环境时如何与Spark交互。您可能会问,“为什么我们在书中这么早就开始讨论部署?一般不都是在书最后讨论部署,不是吗?”

20多年前,当我使用Visual Basic 3 (VB3)构建应用程序时,在项目即将结束时,我运行Visual Basic安装向导来帮助构建3.5英寸软盘。在那个时候,我阅读的《Microsoft Visual Basic 3.0 Programmer’s Guide》一书,部署在第25章中讨论。

快进到今天。您的公司正在运行DevOps或即将运行DevOps,您(可能)听说过像持续集成和持续交付(CICD)这样的术语,并且在流程中部署发生时间比以前早得多。在我最近的一个项目中,团队使用Spark实现了一个数据管道原型;CICD是原型实现的完整部分。部署是非常重要的。理解部署的约束是关键,我鼓励您在项目中尽早这样做。

持续集成和持续部署
CICD,或CI/CD,是指持续集成和持续交付的组合实践。持续集成(CI)是将所有开发人员的工作副本定期合并到共享主线的实践。一天可能好几次。Grady Booch (UML的联合创始人,IBMer,图灵讲师,等等)在他1991年的软件工程方法中创造了CI。极限编程(XP)采用了CI的概念,并提倡每天进行多次集成。CI的主要目标是防止集成问题。CI旨在与测试驱动开发(TDD)编写的自动化单元测试结合使用。最初,这被认为是在提交到主线之前在开发人员的本地环境中运行并通过所有单元测试。这有助于防止一个开发人员正在进行的工作破坏另一个开发人员的副本。对这一概念的最新阐述引入了构建服务器,它会定期或甚至在每次提交之后自动运行单元测试,并将结果报告给开发人员。持续交付(CD)允许团队在短周期内生产软件,确保软件可以在任何时候可靠地发布。它的目标是更快、更频繁地构建、测试和发布软件。通过允许对生产中的应用程序进行更多增量更新,这种方法有助于降低交付更改的成本、时间和风险。直接且可重复的部署过程对于持续交付非常重要。持续交付有时会与持续部署相混淆。在连续部署中,任何通过一系列测试的生产变更都将自动部署到生产中。相反,在持续交付的情况下,软件需要在任何时候可靠地发布,但是发布的时间由人来决定,通常基于业务原因。

因此,不像我在1994年使用VB3,你在第5章就开始探索部署。但是,不要担心:我们仍然尊重传统,因为高级部署(包括管理集群、资源、共享文件等)仍然在第18章中。

首先看一个示例,在这个示例中,数据是在Spark内部,由Spark生成的,从而避免了接入数据的需要。在集群中接入数据比创建自生成的数据集要复杂一些。

然后您将了解与Spark交互的三种方式:

  • 本地模式,通过前几章的示例,您已经熟悉该模式
  • 集群模式(多台计算机或节点)
  • 交互模式(通过shell)

您将为实验搭建环境。了解在多个节点上分片计算资源时的约束条件。现在收集这些经验非常重要,这样在计划部署应用程序时就会有更好的认识。最后,将在集群上运行应用程序。

本章中的实验示例与第5章相关联,因此它们共享相同的存储库。在GitHub中可以下载到https://github.com/jgperrin/net.jgp.books.spark.ch05。

6.1 例子的扩展内容:组件的角色

在前一章中,您了解了如何使用Spark(类和lambda函数)来计算π的近似值。您运行了应用程序,但没有真正查看程序底层发生了什么,也没有考虑体系结构中每个元素的角色。

组件是封装了一组相关函数的逻辑表示。组件在物理上可以是一个包、一个web服务或其他。识别组件的一个好处是可以更容易地识别其接口,这是与组件通信的方式。

在本章的介绍中,您了解了与Spark交互的三种方式。但是,无论您是在本地、集群或交互模式下运行Spark, Spark都使用同一组组件。

每个组件都有一个独特的角色。了解每个组件的运行情况非常重要,这样就可以更容易地调试或优化程序。您将首先快速了解组件及其交互,然后深入了解更多细节。

6.1.1组件及其交互速览

本小节提供了Spark体系结构中每个组件的概览,包括它们之间的链接。您将遵循基于第5章求π的近似值示例应用程序的流程。图6.1将组件放置在体系结构图中。

dea94ba594716bee803b67c579f0d271.png

图6.1 Spark组件和组件之间的交互。数字表示网络调用时,最有可能被启动的顺序。

从应用程序的角度来看,您将建立的唯一连接是通过在master/集群管理器(图6.1中的link 1)中创建会话。表6.1描述了这些链接(links)。“关注级别”专栏解释了您应该关注Spark体系结构中的这个特定项的原因:这在维护、调试或部署Spark时非常有用。

Link

Origin(源)

Destination(目的地)

关注级别

1

Driver

Cluster Manager/master

你需要关注这个链接;应用程序通过这种方式连接到master或cluster manager(集群管理器)。

2

Cluster

Manager/master

Executor

这个链接建立了workers和master之间的连接。worker发起连接,但是数据从master传递给workers。如果该链接断开,集群管理器将不能与executors(执行器)通信。

3

Executor

Executor

executors之间的内部链接;作为开发人员,

我们并不太关心它。

4

Executor

Driver

executor需要能够返回到driver(驱动程序),这意味着driver不能在防火墙之后(当您的第一个应用程序试图连接到云中的Spark集群时,这是一个新手会犯的错误)。如果executors不能与driver通信,它们将不能将数据发回。

表6.1 Spark组件之间的链接(links)(续)

清单6.1是在第5章中学习的应用程序,您在其中计算了π的近似值。在这一章中,我不会解释应用程序做了什么,但是会解释应用程序使用/触发了什么组件。这段代码将在driver节点上运行,但是它将控制和生成其他节点上的活动。这些数字将代码清单6.1链接到图6.1。

实验

这是第五章中的200号实验。可以在GitHub上下载:https:// ithub.com/jgperrin/net.jgp.books.spark.ch05。

代码清单6.1计算π的近似值

package net .jgp.books.spark.ch05.lab200_pi_compute_cluster;...public class PiComputeClusterApp implements Serializable {...     private final class DartMapper         implements MapFunction {...    }     private final class DartReducer implements ReduceFunction {...    }     public static void main(String[] args ) {      PiComputeClusterApp app = new PiComputeClusterApp();       app .start(10);    }     private void start(int slices ) {       int numberOfThrows = 100000 * slices ;...//Link1:session驻留在集群管理器上。      SparkSession spark = SparkSession            .builder()            .appName( "JavaSparkPi on a cluster" )            .master( "spark://un:7077" )            .config( "spark.executor.memory" , "4g" )            .getOrCreate();...      List l = new ArrayList<>( numberOfThrows );       for ( int i = 0; i < numberOfThrows ; i ++) {         l .add( i );      }      //Link2:在executor中创建第一个dataframe。      Dataset incrementalDf = spark            .createDataset( l , Encoders.INT())            .toDF();...//这个步骤被添加到位于集群管理器中的DAG中。      Dataset dartsDs = incrementalDf            .map( new DartMapper(), Encoders.INT());...//Link4:reduce操作的结果被发回应用程序。       int dartsInCircle = dartsDs .reduce( new DartReducer());...      System. out .println( "Pi is roughly " +➥ 4.0 * dartsInCircle / numberOfThrows );       spark .stop();    } }

Spark应用程序作为独立进程在集群上运行。应用程序中的SparkSession对象(也称为驱动程序)协调进程。无论您是在本地模式还是有10,000个节点,您的应用程序都有一个唯一的SparkSession。SparkSession是在构建会话时创建的,如下所示:

SparkSession spark = SparkSession.builder()      .appName( "An app" )      .master( "local[*]" )       .getOrCreate();

作为session的一部分,您还将获得上下文对象:SparkContext。在Spark2.0版本之前,SparkContext是使用Spark的唯一方法。你基本上不需要与SparkContext交互,但是当你需要(访问基础设施信息,创建accumulator,等等,在第17章中描述)时,以下是你如何访问它:

SparkContext sc = spark .sparkContext(); System. out .println( "Running Spark v" + sc .version());

基本上,集群管理器负责在应用程序之间分配资源。但是,要在集群上运行,SparkSession可以连接到几种类型的集群管理器。这可能由您的基础设施、企业架构师或无所不知的专家决定。你可能别无选择。第18章讨论更多的集群管理器选项,包括YARN、Mesos和Kubernetes。

一旦连接上,Spark在集群中的节点上获得executors,这些executors是运行计算和存储应用程序数据的JVM进程。图6.2演示了集群管理器获取资源的过程。

d7eb0be9366472c5294d09de28b03973.png

图6.2 集群管理器的角色之一是在worker节点中查找资源。

接下来,集群管理器将您的应用程序代码发送给executors。您不需要在每个节点上部署应用程序。最后,SparkSession将任务发送给executors运行。

6.1.2 Spark架构的故障排除提示

Spark的体系结构(如6.1.1节中所描述的)可能看起来不太寻常,但仍然很容易理解,至少在数据和软件工程师需要理解的层次上是这样(性能调优肯定需要更深入的知识)。在本节中,您将了解架构的细节和约束。

其中一类典型的错误是:Spark花费了太多的时间或者您永远不会得到结果。如果部署后出现问题,请考虑以下几点:

  • 即使action操作没有将结果返回到应用程序(导出数据时就是这种情况),您也必须始终确保执行程序(executor)能够与驱动程序(driver)对话。与驱动程序对话意味着执行程序和驱动程序不应该被防火墙隔离,也不应该在另一个网络上公开多个IP地址,等等。当应用程序在本地运行(例如在开发中)并试图连接到远程集群时,可能会发生通信中的这些问题。驱动程序必须在其整个生命周期中侦听并接受来自执行程序的连接(查看在附录K的“应用程序配置”部分中spark.driver.port配置项)。
  • 每个应用程序都有自己的executor进程,这些进程在整个应用程序运行期间保持运行,并在多线程中运行任务(task)。这样做的好处是在调度端(每个驱动程序调度自己的任务)和执行程序端(来自不同jvm中运行的不同应用程序的任务)隔离应用程序。但是,这也意味着如果不将数据写入外部存储系统,就不能在不同的Spark应用程序(SparkSession或SparkContext的实例)之间共享数据。
  • Spark与底层集群管理器无关,只要它能够获取executor进程,并且executor进程可以相互通信。可以在支持其他应用程序(如Mesos或YARN)的集群管理器上运行Spark程序(参见第18章)。
  • 由于驱动程序在集群上调度任务,在物理上,它应该运行在靠近worker节点的地方,最好是在同一个局域网上。进程是网络密集型的,当网络靠近时可以减少延迟。在使用云服务时,要同时维护物理节点并不容易。如果您计划在云中运行Spark,请与云运维人员确认机器的物理位置是否接近。

附录R列出了常见的问题和解决方案,以及在哪里可以找到帮助。

6.1.3 更进一步

在6.1节中,我介绍了Spark体系结构,这是部署的基本要求。正如你所想象的,还有更多。

要更进一步,您可以阅读Spark文档,可以在https://spark.apache.org/docs/latest/cluster-overview.html获得。

6.2 构建集群

在6.1节中,了解了如何构建无数据接入的应用程序,了解了与Spark交互的三种方法,并探索了各种组件和它们之间的链接。

这已经为下一个任务提供了足够的知识:在一个真正的集群上部署应用程序。在本节中,您将看到如何执行以下操作:

  • 构建一个集群
  • 设置它的环境
  • 部署应用程序(通过使用Git和Maven构建一个uber JAR)
  • 运行应用程序
  • 分析执行日志
6.2.1 构建适合您的集群

我知道在家里或办公室部署一个分布式环境并不容易,但正如您所知道的,Spark是为在分布式环境中工作而设计的。我将描述使用4个节点的部署,但是如果您愿意,可以在单个节点上工作。我强烈建议至少有两个;这将允许了解网络问题以及如何共享数据、配置和二进制文件(应用程序、jar)。

那么,在集群上工作有哪些选项呢?您有几个选项,可以在家里建立一个分布式环境:

  • 最简单的一种可能是使用云:在云提供商(如Amazon EC2、IBM cloud、OVH或Azure)中获得两个或三个虚拟机。注意,这个选项的成本很难估计。在这一点上,我不推荐Amazon EMR,因为它有一些限制(你将在第18章中发现更多)。你不需要很大的服务器;目标是大于8 GB的内存和32 GB的磁盘。CPU对于这个实验来说并不重要。
  • 第二种选择是在家里安装一个稍微大一点的类似服务器的机器,在上面安装虚拟机或容器。这个选项对每台机器的要求与第一个选项相同;这意味着如果您计划拥有4个节点,那么在物理机器中至少有32gb的RAM。这个选项可以通过Docker或VirtualBox完成。
  • 第三个选择是使用你家里所有的旧电脑,用它建立一个集群,除了内存小于8gb的电脑。这还不包括您的Atari 800XL、Commodore 64、ZX81和其他一些设备。
  • 最后,您可以按照我的方法,购买并从头构建4个节点。我的集群名为CLEGO,可以在我的博客http://jgp.net/clego上找到如何操作(以及我这样命名它的原因)。

在本章中,我将使用CLEGOS的四个节点,因为硬件是为分布式处理设计的。图6.3 显示了该实验使用的集群架构。

如果没有一个以上的节点,您仍然可以按照下面的步骤,仅为节点un执行操作。

2b5bddfb3f6916b909f9747dc3c30661.png

图6.3 本实验中用于部署的架构:使用四个节点。主机被称为un、deux、trois和quatre(法语中的一、二、三、四)。FQDN代表完全限定域名。

6.2.2 设置环境

现在您已经定义了您的环境,接下来需要执行以下操作:

  • 安装Spark。
  • 配置并运行Spark。
  • 下载/上传您的应用程序。
  • 运行它。
您需要在每个节点上安装Spark(详细信息请参阅附录K)。安装非常简单。您不必在每个节点上安装应用程序。在本章的其余部分,我将假设您在/opt/apache-spark中安装了Spark。 在master节点上(本例中为un),进入/opt/apache-spark/sbin目录。 运行master:
$ ./start-master.sh
记住,master不会做很多事情,但它总是需要workers。要运行你的第一个worker,输入以下内容:
$ ./start-slave.sh spark://un:7077
在这个场景中,worker运行在与master相同的物理节点上。

小心您的网络配置

在构建集群时,网络扮演着关键角色。每个节点都应该能够与另一个节点相互通信。检查你需要的端口是可访问的,并希望端口没有被其他应用使用;通常是7077、8080和4040。这些端口不会对互联网开放,只在内部开放。您可以使用ping、telnet进行检查(使用telnet 命令)。不要在任何命令中使用localhost作为主机名。

你总是先启动master,然后启动workers。要检查是否一切正常,请打开浏览器并访问http://un:8080/。这个web界面是由Spark提供的;您不需要启动web服务器或链接web服务器。确保没有在端口8080上运行任何其他应用,或相应地修改端口配置。图6.4显示了结果。

d14376e7b1188d5741e8355698573b53.png

图6.4 master节点只有一个worker。您还可以看到,没有正在运行或已完成的应用程序

当您运行更多的应用程序时,此界面会显示运行的应用程序,您将能够发现关于应用程序及其执行等的更多信息。在6.4.1节中,将看到如何访问应用程序的日志。

现在可以转到下一个节点(在本例中是deux)。转到/opt/apache-spark/sbin。不要运行另一个master,只需启动第二个worker:

$ ./start-slave.sh spark://un:7077
您可以刷新浏览器。图6.5显示了结果。

5ce6a84f1f725f344ea2cc484b174de7.png

图6.5 Spark web界面现在显示两个worker。

因为我有四个节点,所以我将对第三个和第四个节点重复这个操作。我的master节点与我的第一个worker节点在同一个节点上运行。最后,浏览器应该会显示图6.6。

现在,您有了一个工作集群,它由一个master服务器和四个worker组成,可以执行您的工作。物理集群使用4个节点。

f26b30f5695f96626c9b483d86a370ed.png

图6.6  Spark web界面现在显示四个worker。

6.3 构建在集群上运行的应用程序

(未完待续......)  欢迎关注公众号,及时获得最新翻译内容:

c40a428e2f78cab801abe657a0bb74f3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值