首页  >  文章  >  后端开发  >  了解和应用 Apache Spark 调优策略

了解和应用 Apache Spark 调优策略

DDD
DDD原创
2024-11-12 17:55:02712浏览

阅读本文的动机。

  • 自己的经历生活在混乱的时刻和冷静分析的时刻。
  • 我寻找更深入的东西。
  • 我了解到 Spark 如何进行优化。
  • Databricks 优化的“优点”是什么。
  • 可以避免调整和重构的良好实践。

介绍

我一直对关系数据库有很好的接触,后来又接触了像 Spark 这样的分布式系统。最初,我深入研究了 DBMS,既设置复杂的查询、管理,又主要是如何为 DBMS 组合一个执行脚本。当我开始更多地使用 Spark,后来又使用 Databricks 时,最初我在必须构建的场景中没有遇到性能问题,但随着大数据领域真正成为大数据,我开始在例程中遇到性能问题,每个例程都会增加 30%一周,这让我寻找 Spark 如何“在幕后”工作,主要是因为我已经知道 DBMS 是如何工作的,这帮助我理解了我将在这里带来的一些概念。

Apache Spark 组件简要说明

让我们保持简短,因为我希望本文重点关注性能分析场景、技术和最佳实践。

火花核心:

该组件是Spark的基础,它负责内存管理、任务、故障恢复、I/O管理,换句话说,它操作RDD。因此,他是一个拥有很大一部分集群的家伙。

执行人:

这个组件是spark生态系统(集群)真正的worker,它是接收写入或读取命令(任务)的组件,可以在磁盘上,也可以在内存上,也可以在两者上(稍后我会解释为什么会出现这种情况)播放)。

工人:

Workers 对于那些已经熟悉分布式计算的人来说就是字面上的意思,它们是集群的节点,所以它是我上面提到的执行器的“托管”,每个工作器可以包含一个或多个执行器。它负责管理分配给执行者的资源,就好像执行者是助手,工人是仓库工人一样。如果他是他汇报的仓库管理员怎么办?

集群管理器:

这是经理,他为工作人员管理资源(内存和CPU),他决定每个应用程序将有多少执行者以及将分配多少资源,他管理他的''发送的任务boss',我将在下面进一步解释,由于它的职责更高,它还监视集群的状态以从故障中恢复,并根据需要重新分配任务。 (注意:集群管理器有多种类型:Yarn、mesos、kubernetes 以及最简单的独立集群管理器)。

火花上下文:

嗯,这是老板或网关,我说网关是因为任何 Spark 应用程序都会经过它,它是允许应用程序与集群交互的东西,即工作人员和执行者,它允许和管理工作人员之间的任务,通过这种方式,它在配置、执行器数量和内存等资源方面管理整个应用程序。您需要知道任务是如何执行的吗?在这里与这位老板交谈。

所以,以一种说明性的方式:

Entendendo e aplicando estratégias de tunning Apache Spark

现在让我们谈谈性能、调音、速度、速度以及从不同位置听到的一切。

当我与关系银行方面合作时,出现性能问题,主要是在应用程序中的过程或函数或查询中,我分析了以下几个方面:

  1. 这个脚本什么时候运行?目前服务器状况如何?
  2. 有人竞争资源或表锁吗?
  3. 一切都很顺利,没有人阻塞(阻塞)服务器资源很好,太好了...
  4. 现在让我看一下剧本,它的逻辑是表演性的吗?换句话说,无论是谁考虑一起读/写或者逐行考虑(编程成瘾),是否咨询了太多他们不需要的列,带有子查询、CTE 等的可怕查询?我修改了所有这些点(重构)并测试了响应速度和服务器资源的使用情况。当我们要谈论 Apache Spark 时,为什么我要解释这一切?所以......这也适用于 Spark,并且在某种程度上我会说更加复杂,但我们会到达那里。
  5. 我想最后,如果脚本好的话我会分析“石头之路”,即估计的执行计划和实际的执行计划。由此,我可以了解 DBMS 正在使用其统计数据(直方图)做什么,以及它假设其信息遵循哪条路径,以及事实是什么,遵循哪条路径。然后您可以识别诸如:查询中的附加过滤器、性能更高的 JOIN 甚至创建索引或临时表等点。

嗯,我想就是这样,现在这些点与 Apache Spark 有什么共同点?

  • 脚本不是为分布式集合操作而设计的(我说过 Spark 有一个难度“加”,哈哈)。
  • 某个例程运行的时间,如果一个简单的 Spark 作业与另一个消耗所有资源的执行作业(甚至没有)在同一个集群中运行。 (看这里一种著名的 DBMS 锁)。
  • 最后,是的,Apache Spark 有一个执行计划,更准确地说,它有以下阶段:
  1. 逻辑计划。
  2. 物理层面。
  3. 执行策略。
  4. 有时会显示预计费用。

总结一下每一个是什么,尽管有名字,你已经可以得到一个想法:

逻辑计划:
将原始查询表示为一系列逻辑运算。它是查询的抽象形式,而不考虑它的实际执行方式。包括有关将要执行的操作的信息,例如过滤、选择、连接、聚合以及错误的“小事情”,哈哈。

物理平面:
详细说明 Spark 将如何实际执行查询。这包括操作顺序以及将使用哪些算法(例如 DBMS 算法)。它可能包括有关数据如何在执行器之间分区和分配的详细信息。

执行策略:
物理平面可以显示 Spark 可以使用的不同执行策略,例如“Broadcast Join”或“Shuffle Hash Join”,具体取决于操作和数据大小。我也会解释一下执行计划的主要算法,冷静一下...

预计费用:
尽管并不总是显示,但某些计划可能包括计划不同部分的成本估算,帮助您了解处理的哪一部分可能成本最高。

查看Apache Spark执行计划的方法

我们有一个文本形式的“根”形式,使用explain()命令,它将有一个类似于下面的输出,显示一个简单的过滤器和一个数据框:

== 物理计划==
*(2) 过滤器(值 > 1)
- *(2) 项目 [名称#0,值#1]
- *(1) 扫描现有RDD[名称#0, 值#1]

客观地,我们可以通过界面、通过 Spark UI 来分析它,在 Databricks 中我们可以访问它,无论是在单元执行中、在作业中还是在集群中。在 Apache Spark 中,它直接是默认端口 4040 上的 IP。

Spark UI 分为几个有用的部分:

  • 作业:显示应用程序中执行的所有作业的列表。每个作业对应于代码中的一个操作。

  • 阶段:显示组成每个作业的阶段。阶段是可以并行执行的工作细分。

  • 任务:详细说明每个阶段内的各个任务,包括有关任务执行时间和状态的信息。

  • 存储:提供有关 RDD(弹性分布式数据集)的内存和存储使用情况的信息。

  • 环境:显示运行时环境属性,包括 Spark 配置和系统变量。

  • Executors:显示为应用程序创建的执行器的信息,包括内存使用情况、磁盘使用情况和性能统计信息。

在这里我是有等级制度的,好吗?这就是事情发生的顺序。

我想要将图像放在屏幕上!!

Entendendo e aplicando estratégias de tunning Apache Spark

Entendendo e aplicando estratégias de tunning Apache Spark

Entendendo e aplicando estratégias de tunning Apache Spark

Spark 算法以及如何知道谁是调优违规者:

首先,我将解释 Spark UI 界面和执行计划中演示的主要算法,无论是逻辑计划还是物理计划:

注意:记住这里的数据集与 Spark 表相同;)

1。让我们从最著名的扫描开始:

  • FileScan:从输入文件读取数据。它可以针对不同的文件格式进行优化,例如 parquet、ORC、CSV、JSON 等。

2。加入(这个给了一些B.O):

  • Broadcast Hash Join:当其中一个数据集足够小,可以传输到集群中的所有节点时使用,避免 Shuffle(我会详细解释这个东西,但简而言之,这是一种数据 shuffle 操作最终加入)。

  • 随机散列连接:两个数据集(如果您愿意,也可以是表)都会被随机排列,以便相应的键位于同一分区中。当数据集很大,无法传输到其他节点时使用。

  • 排序合并连接:要求在连接之前对两个数据集进行排序。对于已经分区和排序的大型数据集来说它是有效的,也就是说,连接是通过分区和排序的列完成的(例如 df.write.partitionBy("coluna1").sortBy("coluna2").parquet("路径/到/保存/分区")

3。聚合(总和、计数、分组等...):

  • HashAggregate:使用哈希表来聚合数据。它对于适合内存的大型数据集非常有效。

  • 排序聚合。对数据进行排序后进行聚合。当数据无法放入内存时使用。

4。随机播放(小心这个家伙):

  • Shuffle:在分区之间重新分配数据,以进行需要重新组织的操作,例如连接和聚合。就 I/O 和网络而言,这是一项昂贵的操作。

5。交换:

  • 更改分区之间的数据分布。它可用于平衡集群节点之间的工作负载。 (平衡和摆脱洗牌的策略)

Entendendo e aplicando estratégias de tunning Apache Spark

6。项目:

  • 从 DataFrame 或 RDD 中选择列的子集。

7。筛选:

  • 应用条件来过滤数据行。

8。排序:

  • 根据一列或多列对数据进行排序。

上面的所有这些算法都可以像我之前所说的通过explain()命令来观察。

现实生活中的 Shuffle 问题场景:

1。 Join 和 GroupBy 操作
join() 和 groupByKey() 等操作通常会触发 shuffle,从而在分区之间重新分配数据。这可能会导致:
高磁盘 I/O 使用率:Shuffle 会生成许多中间文件,这会使执行器的本地磁盘饱和。
高网络负载:执行器之间传输的数据量可能很大,具体取决于所需的连接数量(映射器数量乘以减速器数量)

  • 身份证明: 在 Spark UI 的“阶段”选项卡上,检查随机读取大小/记录和随机溢出(磁盘)值。这些指标的数量过多表明存在潜在问题。
  1. 分区不平衡(数据倾斜) 当数据在分区之间分布不均匀时,某些任务可能比其他任务花费更长的时间,从而导致整体性能下降。识别是一样的,进入Spark UI,进入作业指的是花费时间的部分(这里有一个好的实践,我将在下面提到)并检查卡住的阶段(它正在运行,但没有进度)并查看 Shuffle 指标,一般来说,内存中的容量很大,并且在刷新时磁盘上开始有容量,这表明这种不平衡达到了内存并开始写入磁盘,显然磁盘速度较慢,然后您坐下来如果你让它出现这种情况,你就哭吧。

缓解

  • 为了缓解与随机播放相关的问题: 减少导致随机播放的操作:只要有可能,尽量减少 使用 groupByKey() 并更喜欢使用 reduceByKey()。调整数量 分区:使用spark.sql.shuffle.partitions调整分区数量 洗牌操作期间的分区。 使用诸如广播连接之类的技术:连接大集合 数据集较小,从而避免不必要的shuffle。

在 Spark UI 中随机排列指标:

Entendendo e aplicando estratégias de tunning Apache Spark

shuffle 的工作原理以及成本高昂的原因:

Entendendo e aplicando estratégias de tunning Apache Spark

最后,也许也是最重要的——良好实践:

  1. 由于 Databricks、Jupyter Notebook 和 Google Colab 的广泛流行,绝大多数人都使用 Notebook 进行工作。因此,将每个查询或转换划分为单独的单元格,这样可以更轻松地识别哪个部分是性能问题。把一切放在一起,有好几个工作,很难知道是哪个阶段。

  2. 使用合并而不是覆盖,我知道这需要更多工作,但它更具逻辑性和执行力,因为合并将使用比在数据湖中再次“转储”覆盖整个表更少的 I/O。

  3. 使用cache()或persist()将中间数据存储在内存中,特别是当它将在多个操作中重用时。这可以减少重新计算时间并提高性能。

  4. 如果你不知道,Spark 运行在 JVM 上,因此它本身就是 Java,当你使用 Python 创建著名的 UDF - 用户定义函数时,你为 Spark 留下了一种“黑匣子”,阻止了它自动优化。只要有可能,请使用针对性能进行优化的内置 Spark SQL 函数。

嗯,我想我已经写下了我想到的一切,我喜欢写文章,因为它可以帮助我记住一些场景。我打算录制一个视频来展示这一切,在实践中使用一些公开数据,我可能会在 Kaggle 上获取它,所以在 LinkedIn 上关注我,以了解与数据、人工智能和软件开发世界相关的一切

--> https://www.linkedin.com/in/airton-lira-junior-6b81a661

在 LinkedIn 上关注我,给我动力,我喜欢反馈,并且我也完全愿意改善知识共享。

如果您已经读到这里,恭喜您!!!我希望它能克服所有性能问题。在下一篇文章中,我将介绍 Databricks 的优势,请在 LinkedIn 上关注我以了解详情。谢谢!!

以上是了解和应用 Apache Spark 调优策略的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn