Compartilhar via

扩展 Azure 流分析作业规模以提高吞吐量

本文介绍如何优化流分析查询以提高流分析作业的吞吐量。 可以使用以下指南缩放作业来处理更高的负载,并利用更多系统资源(例如更多的带宽、更多的 CPU 资源、更多的内存)。

作为先决条件,请阅读以下文章:

案例 1 - 查询本质上可以跨输入分区完全并行化

如果查询本质上可以跨输入分区完全并行化,则可以执行以下步骤:

  • 使用 PARTITION BY 关键字编写高度并行的查询。 有关详细信息,请参阅 在 Azure 流分析中使用查询并行化
  • 根据查询中使用的输出类型,某些输出可以是不可并行的,或者需要进一步的配置来使并行。 例如,Power BI 输出不可并行化。 在发送到输出汇流口之前,始终合并输出。 Blob、表、Azure Data Lake Storage、服务总线和 Azure 函数会自动并行化。 SQL 和 Azure Synapse Analytics 输出具有并行化选项。 事件中心需要设置 PartitionKey 配置以匹配 PARTITION BY 字段(通常 PartitionId)。 对于事件中心,还要特别注意匹配所有输入和所有输出的分区数,以避免在分区之间交叉。
  • 使用 1 个流式处理单元 (SU) V2 (这是单个计算节点的全容量)运行查询,以测量最大可实现的吞吐量;如果使用 GROUP BY,则测量作业可以处理的组数(基数)。 作业达到系统资源限制的一般症状如下。
    • 流单元(SU)% 利用率指标超过 80%。 它表示内存使用率较高。 介绍导致此指标增加的因素: 了解和调整流分析流单元
    • 输出时间戳相对于实际时间落后。 根据查询逻辑,输出时间戳可能会与墙上的时钟时间产生逻辑偏移。 但是,它们的速度应该大致相同。 如果输出时间戳进一步下降,则表示系统过度工作。 它可能是下游输出汇聚点的限流或 CPU 占用率过高的结果。 目前我们不提供 CPU 使用率指标,因此很难区分这两个指标。
      • 如果问题是由于接收器限制,则需要增加输出分区数(以及输入分区以保持作业完全可并行),或增加接收器的资源量(例如 Cosmos DB 的请求单位数)。
    • 在作业关系图中,各输入都有按分区的积压事件度量。 如果积压工作事件指标不断增加,则这也是系统资源受到约束的指标(无论是由于输出接收器限制还是 CPU 过高)。
  • 确定一个 SU V2 作业可以达到的限制后,可以在添加更多 SU 时以线性方式推断作业的处理容量,假设没有任何数据倾斜使某些分区变得“热”。

注释

选择正确的流单元数:因为流分析为每个添加的 1 个 SU V2 创建一个处理节点,因此最好使节点数成为输入分区数的除数,因此分区可以均匀分布到节点中。 例如,您已测量出您的 1 SU V2 作业可以实现 4 MB/秒的处理速度,并且输入分区数为 4。 可以选择使用 2 个 SU V2 运行作业,以实现大约 8 MB/秒的处理速率,或 4 个 SU V2 以达到 16 MB/秒。 然后,根据输入速率,您可以决定什么时候将作业的 SU 数量增加到某个值。

案例 2 - 如果查询不并行。

如果查询不是可并行程度较高的,可以执行以下步骤。

  • 首先从没有 PARTITION BY 的查询开始,以避免分区复杂性,并使用 1 SU V2 运行查询以测量最大负载(如 案例 1)。
  • 如果可以在吞吐量方面实现预期负载,则已完成。 或者,您可以选择在使用 2/3 SU V2 和 1/3 SU V2 的分数节点下运行相同的作业,以确定在您的方案中有效的最小流单元数。
  • 如果无法达到所需的吞吐量,请尝试在查询中没有多个步骤时将查询分解为多个步骤,并为查询中的每个步骤最多分配一个 SU V2。 例如,如果有三个步骤,在“缩放”选项中分配三个 SU V2。
  • 若要运行此类作业,流分析会将每个步骤放在具有专用一个 SU V2 资源的自己的节点上。
  • 如果仍未达到负载目标,可以从离输入更近的步骤开始尝试使用 PARTITION BY 。 对于不可自然分区的 GROUP BY 运算符,可以使用执行分区的本地/全局聚合模式,先执行一个分区的 GROUP BY,然后执行一个非分区的 GROUP BY。 例如,如果要计算每 3 分钟通过每个收费站的汽车数量,并且数据量超出了一个 SU V2 可以处理的数据量。

查询:

WITH Step1 AS (
SELECT COUNT(*) AS Count, TollBoothId, PartitionId
FROM Input1 Partition By PartitionId
GROUP BY TumblingWindow(minute, 3), TollBoothId, PartitionId
)
SELECT SUM(Count) AS Count, TollBoothId
FROM Step1
GROUP BY TumblingWindow(minute, 3), TollBoothId

在查询中,您是在计算每个分区中每个收费亭的汽车数量,然后将所有分区的总和相加。

分区后,对于步骤的每个分区,分配一个 SU V2,以便每个分区可以放置在其自己的处理节点上。

注释

如果查询无法分区,在多步查询中增加额外的 SU 并不总是能够提高吞吐量。 提高性能的一种方法是如步骤 5 中所述,使用本地/全局聚合模式来减少初始步骤的数据量。

案例 3 - 你在作业中运行了大量独立查询。

对于某些 ISV 用例,在单个作业中使用单独的输入和输出处理来自多个租户的数据更为经济高效,最终在单个作业中运行了相当多(例如 20 个)独立查询。 假设每个子查询的负载相对较小。

在这种情况下,您可以按照以下步骤进行。

  • 在这种情况下,请勿在查询中使用 PARTITION BY
  • 如果使用事件中心,请将输入分区计数减少到 2 的最小可能值。
  • 使用一个 SU V2 运行查询。 对于每个子查询的预期负载,请添加尽可能多的此类子查询,直到作业达到系统资源限制。 请参阅 案例 1,了解其发生时的症状。
  • 达到度量的子查询限制后,开始将子查询添加到新作业。 假设没有任何负载偏差,作业运行数与独立查询数的关系应该是比较线性的。 然后,您可以预测需要运行多少 SU V2 作业,以满足您想要服务的租户数量。
  • 在使用引用数据与此类查询进行联接时,应先将输入数据合并,然后再与相同的引用数据进行联接。 然后,根据需要拆分事件。 否则,每个引用数据联接都会在内存中保留引用数据的副本,这可能会不必要地破坏内存使用量。

注释

每个作业安排多少租户? 此查询模式通常具有大量子查询,并生成非常大且复杂的拓扑。 作业的控制器可能无法处理此类大型拓扑。 根据经验法则,1/3 SU V2 作业的租户数量应少于 40 个,而 2/3 和 1 个 SU V2 作业的租户数量应少于 60 个。 超过控制器的容量时,任务将无法成功启动。

获取帮助

如需获取进一步的帮助,可前往 Azure 流分析的 Microsoft 问答页面

后续步骤