排查 Dataflow 自动扩缩问题

本页面介绍如何解决 Dataflow 自动扩缩功能相关的问题,以及如何对自动扩缩功能进行管理。

作业不进行纵向扩容或缩容

本部分介绍工作器可能不会进行纵向扩容或缩容的一些场景。

流处理作业不进行纵向扩容

在流处理流水线有积压数据时,工作器不进行纵向扩容。

当积压数据持续数分钟以内或工作器的 CPU 利用率低于 20% 时,便会出现此问题。

有时,积压数据增多,但 CPU 利用率反而下降。这是因为某些任务不需要高 CPU 利用率,因此添加工作器并不会提升性能。在这些情况下,Dataflow 便不会纵向扩容。如需了解详情,请参阅流式自动扩缩功能。可能导致发生这种情况的原因如下:

  • 流水线属于 I/O 密集型作业。
  • 流水线正在等待外部 RPC 调用。
  • 热键导致工作器 CPU 利用率不均匀。
  • 流水线中的键数量不足。

批处理作业和流处理作业不进行纵向扩容

批处理作业或流处理作业按预期运行,但当需要更多工作器时,作业不进行纵向扩容。

此问题可能是由以下某一原因造成的:

  • 无法访问暂存文件或临时文件。如果您的作业使用 Cloud Storage 存储桶,则该存储桶的生命周期配置可能导致存储桶中的某些对象被删除。 删除的对象包括暂存文件夹和临时文件夹及文件。 如需验证文件是否已被删除,请检查存储桶的生命周期配置。 如果暂存或临时文件夹或文件在作业启动后被删除,则创建新工作器所需的软件包可能不存在。如需解决此问题,请在存储桶中重新创建相应文件夹和文件。
  • 防火墙规则阻止工作器在必要的 TCP 端口上发送和接收流量。防火墙规则可能会阻止工作器启动。Dataflow 工作器需要能够在 TCP 端口 12345 和 12346 上发送和接收流量。如需了解详情(包括解决此问题的步骤),请参阅 Dataflow 的防火墙规则
  • 自定义来源具有返回 NULL 值的 getProgress() 方法。使用自定义来源时,积压指标依赖于自定义来源的 getProgress() 方法的返回值来启动数据收集流程。getProgress() 的默认实现返回的是 NULL 值。若要解决此问题,请确保您的自定义来源会替换掉默认的 getProgress() 方法以返回非 NULL 值。
  • 纵向自动扩缩触发的更新会暂时停用横向自动扩缩。如需了解详情,请参阅对横向自动扩缩的影响
  • 如果您使用的是 Python 流水线中的 map 操作,并且作业不会纵向扩容,您可能需要将 Reshuffle 转换添加到流水线代码中。如需了解详情,请参阅 Apache Beam 文档中的重新分组

流处理作业不进行纵向缩容

当流处理作业的积压数据量较低且 CPU 利用率也较低时,工作器不进行纵向缩容。此问题可能是由多种原因造成的。

  • 如果作业不使用 Streaming Engine,则 Dataflow 会在各工作器之间平衡永久性磁盘的数量。因此,每个工作器的永久性磁盘数量必须相等。例如,如果有 100 个磁盘和 100 个工作器,那么每个工作器都有一个磁盘。 在作业进行纵向缩容时,作业可以有 50 个工作器,每个工作器有两个永久性磁盘。之后,直到作业可以有 25 个工作器,每个工作器有 4 个永久性磁盘,该作业才会再次进行纵向缩容。此外,工作器数量下限是分配给 maxNumWorkers 的值除以 15 所得的值。如需了解详情,请参阅流式自动扩缩流水线的扩缩范围

  • 如果作业使用 Streaming Engine,纵向缩容目标取决于目标 CPU 利用率是否达到 75%。若未达到此 CPU 利用率,系统会停用纵向缩容。

  • 估算的积压时间值需保持在 10 秒钟以内且至少持续两分钟,工作器才会进行纵向缩容。积压时间值的波动可能会导致纵向缩容被停用。此外,低吞吐量也可能会导致估算的时间值出现偏差。

  • 当流水线使用 PeriodicImpulse 时,Dataflow 工作器不会按预期纵向缩容。流式自动扩缩不支持使用 PeriodicImpulse

纵向扩容停止

批处理作业或流处理作业开始纵向扩容,但工作器停止纵向扩容,即使存在积压数据也是如此。

当达到配额限制时,就会出现此问题。

  • Compute Engine 配额:Dataflow 作业受项目的 Compute Engine 配额限制。如果有多个作业正在运行,则项目可能达到其 Compute Engine 配额的上限。在这种情况下,Dataflow 无法增加工作器数量。
  • CPU 配额:Dataflow 作业也受项目的 CPU 配额限制。如果所选工作器类型使用多个 CPU,则项目可能达到 CPU 配额的上限。
  • 外部 IP 地址配额:如果您的作业使用外部 IP 地址与资源进行通信,那么您将需要与工作器一样多的外部 IP 地址。当工作器数量增加时,所用外部 IP 地址的数量也会增加。达到 IP 地址限制时,工作器便会停止纵向扩容。

此外,如果您选择的区域已无富余资源,您将无法创建该类型的新资源,即使您的区域或项目中有剩余配额也是如此。例如,您可能仍有用于在 us-central1 中创建外部 IP 地址的配额,但该区域中可能没有可用的 IP 地址。如需了解详情,请参阅配额和资源可用性

如需解决此问题,请申请增加配额或在其他区域运行作业。

工作器利用率提示无效

您可以设置工作器利用率提示,但自动扩缩行为不会改变。

如需了解此问题,请前往工作器 CPU 利用率图表,然后检查是否主动使用工作器利用率提示。如果正在使用该提示,图表会显示 CPU utilization hint (actively used by autoscaler)。否则,系统会显示 CPU utilization hint (not actively used by autoscaler)

利用率提示只是影响自动扩缩的一个因素。下表列出了自动扩缩器可能不会主动使用该提示的一些原因:

观察到的扩缩行为 原因 要检查的指标
没有变化
  • 已达到工作器数量的下限或上限。
  • 工作器数量受并行处理的密钥数量的限制。
  • 作业会受到外部 RPC 的节流。
  • 纵向缩容调整幅度过小,或者 Dataflow 抑制了纵向缩容。如需了解详情,请参阅流式自动扩缩启发法
纵向扩容
  • 高积压或高延迟目标替换了提示。
  • 工作器数量下限已更新为高于当前工作器数量的值。
纵向缩容
  • 工作器数量上限已更新为低于当前工作器数量的值。

如需了解详情,请参阅流式自动扩缩启发法

自动扩缩指标存在缺口

自动扩缩指标中存在短暂的间隔。

如果后端任务重启,可能会出现此问题。指标的这些缺口并不表示自动扩缩或流处理作业的健康状况存在问题。

CPU 分布不均匀

当作业自动扩缩时,CPU 利用率在工作器之间分布不均匀。某些工作器的 CPU 利用率、系统延迟时间或数据新鲜度比其他工作器更高。

如果您的数据包含热键,则可能会出现此问题。热键是具有很多元素并对流水线性能造成不利影响的键。每个键必须由单个工作器处理,因此无法在多个工作器之间拆分工作负载。

如需了解详情,请参阅热键错误指南

请求状态读取的工作项在后端不再有效

在流式流水线中的工作器虚拟机实例与 Streaming Engine 任务进行通信期间,会发生以下错误:

The work item requesting state read is no longer valid on the backend.
The work has already completed or will be retried.
This is expected during autoscaling events.

在自动扩缩期间,工作器虚拟机实例会与多个 Streaming Engine 任务进行通信,并且每个任务会为多个工作器虚拟机实例提供服务。 工作项键用于分发工作。每个任务和工作器虚拟机实例都具有一组键范围,并且这些范围的分布会动态变化。例如,在自动扩缩期间,调整作业大小就可能会导致键范围分布发生变化。当键范围发生变化时,就可能会发生此错误。在这种情况下该错误属于正常现象,除非您发现这些消息表明流水线性能不佳,否则便可忽略该错误。

Streaming Engine 资源不足

如果 Streaming Engine 无法分配您请求的最小数量的工作器,将返回以下错误:

Streaming Engine does not currently have enough resources available to fulfill
the request.

若要解决此问题,您可以尝试设置较小的工作器数量下限。请参阅设置自动扩缩范围

流式自动扩缩流水线的扩缩范围

本部分详细介绍流式自动扩缩流水线的扩缩范围。

Java

对于不使用 Streaming Engine 的流式自动扩缩作业,Dataflow 服务会为每个工作器分配 1 至 15 个永久性磁盘。这种分配方式意味着,流式自动扩缩流水线使用的工作器数量下限为 N/15,其中 N 为 --maxNumWorkers 的值。

对于使用 Streaming Engine 的流式自动扩缩作业,工作器数量下限为 1 个。

Dataflow 会平衡各工作器之间的永久性磁盘数量。例如,如果流水线在稳定状态下需要三或四个工作器,您可以设置 --maxNumWorkers=15。流水线会自动在 1 至 15 个工作器之间进行扩缩;使用 1、2、3、4、5、8 或 15 个工作器时,每个工作器所需的永久性磁盘数量分别是 15、8、5、4、3、2 或 1。

--maxNumWorkers 的上限为 1000。

Python

对于不使用 Streaming Engine 的流式自动扩缩作业,Dataflow 服务会为每个工作器分配 1 至 15 个永久性磁盘。这种分配方式意味着,流式自动扩缩流水线使用的工作器数量下限为 N/15,其中 N 为 --max_num_workers 的值。

对于使用 Streaming Engine 的流式自动扩缩作业,工作器数量下限为 1 个。

Dataflow 会平衡各工作器之间的永久性磁盘数量。例如,如果流水线在稳定状态下需要三或四个工作器,您可以设置 --max_num_workers=15。流水线会自动在 1 至 15 个工作器之间进行扩缩;使用 1、2、3、4、5、8 或 15 个工作器时,每个工作器所需的永久性磁盘数量分别是 15、8、5、4、3、2 或 1。

--max_num_workers 的上限为 1000。

Go

对于不使用 Streaming Engine 的流式自动扩缩作业,Dataflow 服务会为每个工作器分配 1 至 15 个永久性磁盘。这种分配方式意味着,流式自动扩缩流水线使用的工作器数量下限为 N/15,其中 N 为 --max_num_workers 的值。

对于使用 Streaming Engine 的流式自动扩缩作业,工作器数量下限为 1 个。

Dataflow 会平衡各工作器之间的永久性磁盘数量。例如,如果流水线在稳定状态下需要三或四个工作器,您可以设置 --max_num_workers=15。流水线会自动在 1 至 15 个工作器之间进行扩缩;使用 1、2、3、4、5、8 或 15 个工作器时,每个工作器所需的永久性磁盘数量分别是 15、8、5、4、3、2 或 1。

--max_num_workers 的上限为 1000。

流式自动扩缩功能可使用的工作器数量上限

Java

Dataflow 运行时使用的工作器数量不超过您项目的 Compute Engine 实例计数配额或 maxNumWorkers 值(以较小者为准)。

Python

Dataflow 运行时使用的工作器数量不超过您项目的 Compute Engine 实例计数配额或 max_num_workers 值(以较小者为准)。

Go

Dataflow 运行时使用的工作器数量不超过您项目的 Compute Engine 实例计数配额或 max_num_workers 值(以较小者为准)。

限制自动扩缩功能以减少对结算费用的影响

如果您不希望因自动扩缩功能而增加结算费用,您可以限制流处理作业可以使用的工作器数量上限。

Java

您可以指定 --maxNumWorkers,以此限制用于处理作业的扩缩范围。

Python

您可以指定 --max_num_workers,以此限制用于处理作业的扩缩范围。

Go

您可以指定 --max_num_workers,以此限制用于处理作业的扩缩范围。

更改缩放范围

如需了解如何更改流处理流水线的扩缩范围,请参阅设置自动扩缩范围

关闭流处理流水线上的自动扩缩功能

如需关闭流处理流水线上的自动扩缩功能,请按以下步骤操作。

Java

只需设置 --autoscalingAlgorithm=NONE。如需了解详情,请参阅停用横向自动扩缩

Python

只需设置 --autoscaling_algorithm=NONE。如需了解详情,请参阅停用横向自动扩缩

Go

只需设置 --autoscaling_algorithm=NONE。如需了解详情,请参阅停用横向自动扩缩

使用固定数量的工作器

对于不使用 Streaming Engine 的流处理作业,默认行为是使用固定数量的工作器。要在这些流水线上使用流式自动扩缩功能,您必须明确选择启用,因为默认情况下该功能未启用。