本文介绍性能效率的最佳做法,内容按照以下部分中列出的体系结构原则进行组织。
1.垂直缩放、水平缩放和线性可伸缩性
在讨论最佳做法之前,让我们先了解有关分布式计算的几个概念:水平缩放、垂直缩放和线性可伸缩性。
- 垂直缩放:通过在单台计算机上添加或删除资源(通常是 CPU、内存或 GPU)来垂直缩放。 这通常意味着停止工作负载,将其移动到更大的计算机上,然后重新启动它。 垂直缩放存在限制:可能没有更大的计算机,或者下一个更大计算机的价格可能令人望而却步。
- 水平缩放:通过在分布式系统中添加或删除节点来水平缩放。 达到垂直缩放限制时,解决方案是水平缩放:分布式计算使用具有多个计算机(称为群集)的系统来运行工作负载。 重要的是要理解,要做到这一点,工作负载必须为并行执行做好准备,正如 Databricks Data Intelligence 平台、Apache Spark 和 Photon 引擎支持的那样。 这使得可将多台便宜的计算机组合成一个更大的计算系统。 需要更多计算资源时,水平缩放会向群集添加更多节点,并删除不再需要的节点。 虽然技术上没有限制(Spark 引擎负责负载均衡的复杂部分),但大量节点确实增加了管理的复杂性。
- 线性可伸缩性:是指在向系统添加更多资源时,吞吐量和已用资源之间的关系是线性的。 仅当并行任务是独立的,才有可能。 否则,需要将一组节点上的中间结果传递到群集中的另一组节点上,以便进行进一步计算。 节点之间的这种数据交换涉及到通过网络将结果从一组节点传输到另一组节点,这需要相当长的时间。 一般而言,分布式计算在管理数据的分布和交换方面会产生一些开销。 因此,可以在单个节点上分析的小型数据集工作负载在分布式系统上运行时可能反而更慢。 Databricks Data Intelligence 平台提供灵活计算(单节点和分布式)来满足工作负载的独特需求。
2.使用无服务器体系结构
使用无服务器计算
借助 Databricks Data Intelligence Platform 上的 无服务器计算 ,计算层在客户的 Azure Databricks 帐户中运行。 这些服务由 Databricks 完全管理并不断增强。 客户只为他们使用的内容付费外,此外这还提高了工作效率:
- 云管理员不再需要管理复杂的云环境,例如调整配额、创建和维护网络资源以及连接到计费源。 他们可以将时间集中在价值更高的项目上,而不是管理低级别的云组件。
- 用户可受益于接近零的群集启动延迟和改进的查询并发性。
Databricks 为不同的工作负载提供托管服务:
无服务器 SQL 仓库,用于 SQL 工作负载
工作区管理员可创建支持即时计算并由 Databricks 管理的无服务器 SQL 仓库。 将它们与 Databricks SQL 查询一起使用,就像平时使用原始 Databricks SQL 仓库一样。 无服务器计算可使 SQL 仓库非常快地启动,基础结构由 Databricks 进行管理和优化。
无服务器作业,用于实现高效可靠的工作流
借助作业的无服务器计算,可以在不配置和部署基础结构的情况下运行 Databricks 作业。 借助无服务器计算,可以专注于实现数据处理和分析管道,Databricks 可以有效地管理计算资源,包括优化和缩放工作负载的计算。 对于运行作业的计算资源,会自动启用自动缩放和 Photon。
可以通过查询可计费用量系统表来监视使用无服务器计算的作业的成本。
-
如果为工作区启用了无服务器交互式计算,则工作区中的所有用户都可以访问适用于笔记本的无服务器计算。 不需要其他权限。
使用企业级模型服务
Mosaic AI 模型服务为部署、治理和查询 AI 模型提供统一的接口。 你提供的每个模型都可用作 REST API,可以集成到 Web 或客户端应用程序中。
模型服务提供高度可用的低延迟服务来部署模型。 该服务会自动纵向扩展或纵向缩减以满足需求变化,节省基础结构成本,同时优化延迟性能。 此功能使用无服务器计算。
3.根据性能要求设计工作负载
了解数据引入和访问模式
从性能角度来看,数据访问模式(例如“聚合与点访问”或“扫描与搜索”)的行为会有所不同,具体取决于数据大小。 较大文件对于扫描查询更有效,而较小文件更适合搜索,因为需要读取的数据更少就能找到特定的行。
对于引入模式,通常会使用 DML 语句。 当数据聚类时,DML 语句的性能最高,你可以简单地隔离数据部分。 在引入期间保持数据聚类和可隔离性非常重要:考虑保留自然时间排序顺序,并将尽可能多的筛选器应用于引入目标表。 对于仅追加和覆盖引入工作负载,无需考虑太多,因为这是一个相对便宜的操作。
引入和访问模式通常指向明显的数据布局和聚类。 如果不是,请确定什么对你的业务更重要,并专注于如何更好地实现这一目标。
在有利于并行计算的情况下使用它
价值实现时间是处理数据时的一个重要维度。 虽然许多用例可以在单个计算机上轻松实现(小型数据、很少和简单的计算步骤),但通常有用例需要处理大型数据集,由于复杂的算法而运行很长时间,或者需要重复 100 和 1000 次。
Databricks 平台的群集环境是高效分配这些工作负载的极佳环境。 它自动跨群集的所有节点并行化 SQL 查询,并提供适用于 Python 和 Scala 的库来实现相同的目的。 在后台,Apache Spark 和 Photon 引擎会分析查询,确定并行执行的最佳方式,并以弹性方式管理分布式执行。
与批处理任务一样,结构化流式处理在整个群集中分配流式处理作业以提供最佳性能。
使用并行计算的最简单方法之一是使用 Lakeflow 声明性管道。 在 SQL 或 Python 中声明作业的任务和依赖项,然后 Lakeflow 声明性管道处理执行规划、高效的基础结构设置、作业执行和监视。
Pandas 是数据科学家常用的一个 Python 包,可为 Python 编程语言提供易于使用的数据结构和数据分析工具。 但是,Pandas 无法扩展以处理大规模数据。 Spark 上的 Pandas API 可提供在 Apache Spark 上运行的、与 Pandas 等效的 API,从而填补这一空白。
此外,该平台还在标准机器学习库 MLlib 中提供了并行化机器学习算法。 它支持开箱即用的多 GPU 用法。 还可以使用 DeepSpeed 分发服务器或 TorchDistributor 将深度学习并行化。
分析整个执行链
大多数管道或消耗模式都涉及一系列系统。 例如,使用 BI 工具时,性能受多种因素影响:
- BI 工具本身。
- 连接 BI 工具和 SQL 引擎的连接器。
- BI 工具向其发送查询的 SQL 引擎。
为了获得一流的性能,必须考虑并选择/优化整个链来获得最佳性能。
优先使用较大的群集
规划较大的群集,尤其是当工作负载线性缩放时。 在这种情况下,对工作负载使用大型群集并不比使用较小群集更昂贵。 而速度却更快。 关键在于根据工作负载的持续时间租用群集。 因此,如果启动两个工作集群并且用时一小时,则需要为这些工作者支付整整一小时的费用。 同样,如果你启动一个由四个工作节点组成的群集,并且只需半小时(此时线性可伸缩性会发挥作用),那么成本是相同的。 如果成本是非常灵活 SLA 的主要驱动因素,则自动缩放群集通常是最便宜的,但不一定是最快的。
注意
无服务器计算不需要首选大型群集,因为它会自动管理群集。
使用预测优化
为了提高性能,表需要定期维护,例如优化数据的布局、清理不再需要的旧版本的数据文件以及更新数据的聚类分析。 为了确保最佳性能,其中一些任务需要充分了解跨平台的数据访问模式。
Databricks Unity 目录管理其管理的表的所有读取和写入,并了解跨平台的所有查询模式。 根据这些模式, 预测优化 可以根据实际使用数据的方式优化表,这通常会导致显著的性能改进。 此外,预测优化无需手动管理 Databricks 上 Delta 表的维护操作。 平台会自动识别那些需要维护操作且会从中受益的表,并为用户执行这些操作。
Databricks 建议你为帐户、目录或架构 启用预测优化 (如尚未启用)(与 管理表一样)。
使用 Unity Catalog 托管表
Unity 目录中的 表可以作为托管表 或 外部表创建。 若要创建外部表,必须指定对象存储位置,并负责维护和优化这些表。 对于托管表,Databricks 管理整个数据生命周期,包括文件布局和自动启用的 预测优化,这通常会导致显著的性能改进。
建议对 Databricks 中管理的所有表格数据使用 Unity 目录托管表 。
使用本机 Spark 操作
用户定义的函数 (UDF) 是扩展 Spark SQL 功能的好方法。 但是,如果存在本机函数,请不要使用 Python 或 Scala UDF:
原因:
- 要在 Python 和 Spark 之间传输数据,需要使用序列化。 这会显著降低查询速度。
- 增加了实现和测试平台中已存在的功能的工作。
如果缺少原生函数,应将其实现为 Python UDF,请使用 Pandas UDF。 Apache Arrow 确保数据在 Spark 和 Python 之间高效地来回移动。
使用本地平台引擎
Photon 是 Azure Databricks 上的引擎,可直接在数据湖上以低成本提供快速查询性能 - 从数据引入、ETL、流、数据科学到交互式查询。 Photon 与 Apache Spark API 兼容,因此只需启用就能使用 - 无需更改代码,也没有锁定。
Photon 是高性能运行时的一部分,可更快运行现有 SQL 和数据帧 API 调用,从而降低每个工作负载的总成本。 Databricks SQL 仓库中默认使用 Photon。
了解硬件和工作负载类型
并非所有云 VM 都是相同的。 云提供商提供的各种计算机系列都是不同的,需要重点考虑这一点。 有明显的差别 - RAM 和核心 – 还有更细微的差别 – 处理器类型和代次、网络带宽保证,以及本地高速存储、本地磁盘与远程磁盘。 "即期市场也存在差异。" 在为工作负载确定最佳 VM 类型之前,应了解这些差异。
注意
无服务器计算不需要这样做,因为它会自动管理群集。
使用缓存
缓存将频繁访问的数据存储在更快的介质中,与访问原始数据源相比缩短了检索数据所需的时间。 这会降低延迟并加快响应时间,从而显着提高应用程序的整体性能和用户体验。 通过最大程度地减少对原始数据源的请求数,缓存有助于降低网络流量和数据传输成本。 这种效率提升对于依赖外部 API 或按使用付费数据库的应用程序尤其有利。 它可以帮助在整个系统中更均匀地分配负载,从而防止出现瓶颈和潜在的停机时间。
Azure Databricks 中提供了几种类型的缓存。 以下是每个类型的特征:
使用磁盘缓存
磁盘缓存(以前称为“增量缓存”)可将远程数据的副本存储在虚拟机的本地磁盘(例如 SSD)上。 它可以提高各种查询的性能,但不能用于存储任意子查询的结果。 磁盘缓存会自动检测创建或删除数据文件的时间,并相应地更新其内容。 建议的(也是最简单的)磁盘缓存使用方法是在配置群集时选择使用 SSD 卷的工作器类型。 为这样的工作人员启用了磁盘缓存并进行了配置。
避免 Spark 缓存
Spark 缓存(使用
.persist()
和.unpersist()
)可以存储任何子查询数据的结果,以及以非 Parquet 格式(例如 CSV、JSON 和 ORC)存储的数据。 但是,在查询中使用不正确的位置可能会消耗所有内存并显著降低查询速度。 根据经验,避免 Spark 缓存。查询结果缓存
按群集缓存通过 SQL 仓库进行的所有查询的查询结果。 若要从查询结果缓存受益,请将重点放在确定性查询上,例如不要使用
= NOW()
之类的谓词。 如果查询是确定性的,并且基础数据是 Delta 格式且未更改,则 SQL 仓库将直接从查询结果缓存中返回结果。Databricks SQL UI 缓存
在 Databricks SQL UI 中按用户缓存所有查询和旧版仪表板结果。
使用压缩
Azure Databricks 上的 Delta Lake 可提高表中读取查询的速度。 一种方法是将小文件合并成较大的文件。 通过运行 OPTIMIZE 命令触发压缩。 请参阅优化数据文件布局。
Delta Lake 提供了选项,可用于自动配置写入和OPTIMIZE操作的目标文件大小。 Databricks 会自动优化其中的许多设置,并启用通过找出适当文件大小来自动提高表性能的功能:
- 自动压缩合并 Delta 表分区中的小文件,自动减少小文件存在的问题。 自动压缩发生在向表进行写入的操作成功后,在执行了写入操作的群集上同步运行。 自动压缩仅压缩以前尚未压缩过的文件。
- 优化写入在数据写入时优化文件大小,有利于后续对表的读取。 优化写入对已分区表的效果最好,因为它们可以减少写入每个分区的小文件数。
有关更多详细信息,请参阅配置 Delta Lake 以控制数据文件大小。
使用数据跳过
数据跳过可以通过跳过不符合查询条件的数据来显着提高查询性能。 这样可以减少需要读取和处理的数据量,从而加快查询执行时间。
为实现此目的,将数据写入 Delta 表时,会自动收集数据跳过信息(默认情况下,Azure Databricks 上的 Delta Lake 会收集表架构中定义的前 32 列的统计信息)。 Azure Databricks 上的 Delta Lake 会在查询时使用此信息(最小值和最大值)来提供更快的查询。 请参阅 Delta Lake 的数据跳过。
可应用以下技术来实现数据跳过:
Z 排序,一种用于并置同一组文件中的相关信息的技术。 Azure Databricks 上的 Delta Lake 数据跳过算法会自动使用此共置技术。 此行为显著减少了 Delta Lake 必须读取的数据量。
Liquid 聚类分析可简化数据布局决策并优化查询性能。 随着时间的推移,它将替换分区和 Z 排序。 Databricks 建议对所有新的 delta 表使用液体聚类。 Liquid 聚类分析提供了在不重写现有数据的情况下重新定义聚类分析键的灵活性,从而使数据布局能够随着分析需求和时间推移而演变。 Databricks 建议对所有新的 delta 表使用液体聚类。
具有以下特征的表可从 liquid 聚类分析中受益:
- 按高基数的列进行筛选。
- 数据分布明显偏斜。
- 增长迅速且需要维护和优化工作量。
- 表具有并发写入要求。
- 表的访问模式随时间变化。
- 典型的分区键可能使表具有过多或过少的分区。
有关更多详细信息和技术,请参阅优化 Databricks、Spark 和 Delta Lake 工作负载的综合指南。
避免过度分区
过去,分区是最常见的数据跳过方式。 但是,分区是静态的,并且本身呈现为文件系统层次结构。 当访问模式随时间变化时,没有简单的方法来更改分区。 通常,分区会导致过度分区 - 换言之,有太多的分区包含太小的文件,导致查询性能不佳。
Databricks 建议不要对大小低于 1 TB 的表进行分区,并且如果希望每个分区中的数据至少为 1 GB,则仅按列进行分区。
同时,比分区更好的选择是 Z 排序或较新的 Liquid 聚类分析(见上文)。
优化联接性能
考虑范围联接优化。
当两个关系通过区间中的某个点或区间重叠条件进行连接时,会发生范围连接。 Databricks Runtime 中的范围联接优化支持可以在查询性能方面带来数量级的改进,但需要仔细地进行手动优化。
使用自适应查询执行。
自适应查询执行 (AQE) 是在查询执行期间发生的查询重新优化。 它有 4 个主要功能:
- 将排序合并联接动态更改为广播哈希联接。
- 随机交换后动态合并分区。
- 在排序合并联接和随机哈希联接中动态处理倾斜。
- 动态检测并传播空关系。
建议保持 AQE 启用。 可以单独配置不同的功能。
有关更多详细信息,请参阅优化 Databricks、Spark 和 Delta Lake 工作负载的综合指南。
运行 analyze table 以收集表统计信息
ANALYZE TABLE
语句收集指定架构中表的统计信息。
查询优化器使用这些统计信息生成最佳查询计划,从而选择正确的联接类型、在哈希联接中选择正确的生成端,或者在多路联接中校准联接顺序。
预测优化会自动运行 ANALYZE
(公共预览版),这是用于收集 Unity 目录托管表上的统计信息的命令。 Databricks 建议为所有 Unity Catalog 托管表启用预测优化,以简化数据维护并降低存储成本。 请参阅 Unity Catalog 托管表的预测优化。
4.在开发范围内运行性能测试
基于代表生产数据的数据进行测试
基于生产数据(只读)或类似数据运行性能测试。 使用相似数据时,数量、文件布局和数据倾斜等特征应该与生产数据相似,因为这对性能有重大影响。
考虑预热资源
与查询和数据格式无关,群集上的第一个查询始终比后续查询要慢。 这是因为所有不同的子系统都在启动和读取所需的所有数据。 预热对性能测试结果的影响很大:
- 预热群集:群集资源需要在多个层上初始化。 可以预热群集:Databricks 池是一组空闲且随时可用的实例。 使用这些空闲实例创建群集节点后,可以减少群集启动和自动缩放的时间。
- 预热缓存:当缓存是设置的一部分时,首次运行可确保数据位于缓存中,从而加快后续作业的速度。 可以通过运行特定查询初始化缓存(例如在群集重启后)来预热缓存。 这可以显著提高前几个查询的性能。
因此,若要了解不同方案的行为,请测试首次执行(使用和不使用预热)和后续执行的性能。
识别瓶颈
瓶颈是工作负载中随着生产中负载的增加而降低整体性能的方面。 在设计时识别瓶颈并针对更高的工作负载进行测试有助于保持生产环境中工作负载的稳定性。
5.监视性能
监视查询性能
监视查询性能可帮助你了解不同查询如何使用资源。 可以识别运行缓慢的查询,从而确定系统中的性能瓶颈。 还可以识别正在消耗大量系统资源,可能导致不稳定或停机的查询。 此信息可帮助你优化资源分配、减少浪费并确保有效使用资源。
Databricks Data Intelligence 平台具有各种监视功能(请参阅卓越运营 - 设置监视、警报和日志记录),其中一些功能可用于性能监视:
- 查询配置文件:使用查询配置文件功能排查查询执行期间的性能瓶颈问题。 它提供了每个查询任务和相关指标的可视化,例如花费的时间、处理的行数和使用的内存。
- SQL 仓库监视:通过查看实时统计信息、峰值查询计数图表、正在运行的群集图表和查询历史记录表来监视 SQL 仓库
监视流式处理工作负载
流式监视使你能够分析数据并检测问题,从而实时了解系统的性能和行为。 通过分析流式处理数据,可以识别趋势、模式和优化机会。 这可帮助你微调系统、提高资源利用率并降低成本。
对于流式处理查询,请使用 Spark UI 中的内置结构化流式处理监视,或者使用 Apache Spark 流式处理查询侦听器接口将指标推送到外部服务。
监视工作表现
作业监视 有助于识别和解决 Lakeflow 作业中的问题,例如故障、延迟或性能瓶颈。 作业监视提供对作业性能的见解,使你能够优化资源利用率、减少占用并提高整体效率。