常见错误指南

本页面介绍了运行 Dataflow 作业时可能会遇到的一些常见错误,并推荐了处理这些错误的一些操作流程。

资源库存不足错误:

作业消息:

作业提交错误:

工作器日志:

输入和输出错误:

工作器启动错误:

日志:

建议:

资源库存不足错误

解决资源池耗尽错误

有时,创建 Google Cloud 资源时,您可能会看到资源池耗尽错误。此错误表示特定可用区中特定资源出现暂时的库存不足情况。消息格式如下:

ERROR: ZONE_RESOURCE_POOL_EXHAUSTED

要解决此问题,您可以等待一段时间,也可以在另一个可用区创建相同的资源。我们建议的最佳做法是,将资源分布到多个可用区和区域,以防止服务中断。

作业消息

The job failed because a work item failed 4 times.

如果由于代码抛出异常或崩溃,某个操作导致工作器代码失败四次,Dataflow 将标示该作业失败,并显示 a work item failed 4 times 消息。 您无法配置此失败阈值。 如需了解详情,请参阅流水线错误和异常处理

在该作业的 Cloud Monitoring 日志中查看这四次失败情况。在工作器日志中查找显示异常或错误的错误级别严重级别日志条目。您应该至少看到四个异常或错误。

用户代码中的编码错误、IO 异常或意外行为。

Apache Beam SDK 和 Dataflow 工作器依赖于常见的第三方组件。而这些组件又会导入其他依赖项。版本冲突可能导致服务出现意外行为。如果您在代码中使用任何这类的软件包,请注意有些库不向前兼容。因此您可能需要在执行过程的范围内固定使用列明的版本。SDK 和工作器依赖项包含依赖项及其所需版本的列表。

作业曾经可以运行,现在却失败了,并显示 Staged package...is inaccessible

  • 确认用于暂存的 Cloud Storage 存储分区没有会导致暂存软件包被删除的 TTL 设置
  • 验证您的 Dataflow 项目的控制器服务帐号有权访问用于暂存的 Cloud Storage 存储桶。权限不足可能是由以下原因造成的:

    • 用于暂存的 Cloud Storage 存储桶位于其他项目中。
    • 用于暂存的 Cloud Storage 存储桶已从精细访问权限迁移到统一存储桶级访问权限。由于 IAM 政策与 ACL 政策不一致,因此将暂存存储桶迁移到统一存储桶级访问权限会禁止使用 Cloud Storage 资源的 ACL,其中包括您的 Dataflow 项目的控制器服务账号拥有的暂存存储桶权限。

如需了解详情,请参阅跨 Google Cloud 项目访问 Cloud Storage 存储桶

Flex 模板轮询超时

您的 Flex 模板作业可能会返回以下错误消息:

Timeout in polling result file: ${file_path}.
Service account: ${service_account_email}
Image URL: ${image_url}
Troubleshooting guide at https://cloud.google.com/dataflow/docs/guides/common-errors#timeout-polling

原因可能如下:

  1. 基础 Docker 映像已被替换。
  2. 填充 ${service_account_email} 的服务帐号没有某些必要的权限。
  3. 创建图表的程序完成所需时间过长。
  4. (仅限 Python)requirements.txt 文件存在问题。
  5. 发生暂时性错误。

在发生暂时性错误时除了检查作业日志并重试之外,以下是一些额外的问题排查步骤。

验证 Docker 入口点

此步骤适用于通过自定义 Docker 映像(而不是使用某个提供的模板)运行模板的用户。

使用以下命令检查容器入口点:

docker inspect $TEMPLATE_IMAGE

您应该会看到以下内容:

Java

/opt/google/dataflow/java_template_launcher

Python

/opt/google/dataflow/python_template_launcher

如果您看到其他输出,则表示 Docker 容器的入口点已被替换。将 $TEMPLATE_IMAGE 恢复为默认设置。

检查服务帐号权限

检查消息中提及的服务帐号是否具备以下权限:

  • 该服务帐号必须能够读取和写入填充消息中的 ${file_path} 的 Cloud Storage 路径。
  • 该服务帐号能够读取填充消息中的 ${image_url} 的 Docker 映像。

检查启动器程序是否未能退出

构建流水线的程序必须先完成,然后流水线才能启动。轮询错误可能执行此操作所花费的时间太长。

您可以执行以下操作在代码中查找原因:

  • 检查作业日志,看看是否有任何操作似乎需要很长时间才能完成。例如,外部资源的请求。
  • 确保没有线程阻止程序退出。某些客户端可能会创建自己的线程,如果这些客户端未关闭,则程序将无限期等待这些线程联接。

请注意,直接启动(未使用模板)的流水线没有这些限制,因此如果流水线直接启动时可正常运行,但作为模板启动时失败,那么这可能就是根本原因。

(仅限 Python)从需求文件中移除 Apache Beam

如果您的 Dockerfile 包含具有 apache-beam[gcp]requirements.txt,那么您应该将其从文件中移除并单独安装。例如:

RUN pip install apache-beam[gcp]
RUN pip install -U -r ./requirements.txt

已知将 Beam 放入需求文件中会导致启动时间过长,这通常会导致超时。

Python 中的 Flex 模板作业排队并超时

如果您使用 Flex 模板和 Python 运行 Dataflow 作业,则作业可能会排队一段时间,然后运行失败。系统会显示 Timeout in polling 错误消息。

该错误是由用于安装所需依赖项的 requirements.txt 文件引起的。当您启动 Dataflow 作业时,系统会首先暂存所有依赖项,以使工作器虚拟机能够访问这些文件。该过程涉及下载和重新编译 requirements.txt 文件中的每个直接和间接依赖项。一些依赖项可能需要几分钟时间才能完成编译,尤其是 Pyarrow,这是 Apache Beam 和大多数 Google Cloud 客户端库使用的间接依赖项。

如需解决此问题,请执行以下步骤:

  1. 将 Dockerfile 中预编译的依赖项下载到 Dataflow 暂存目录。

  2. 将环境变量 PIP_NO_DEPS 设置为 True

    此设置可防止 pip 重新下载并重新编译所有依赖项,这有助于防止超时错误。

以下代码示例展示了如何预下载依赖项。

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM gcr.io/dataflow-templates-base/python3-template-launcher-base

ENV FLEX_TEMPLATE_PYTHON_REQUIREMENTS_FILE="/template/requirements.txt"
ENV FLEX_TEMPLATE_PYTHON_PY_FILE="/template/streaming_beam.py"

COPY . /template

# We could get rid of installing libffi-dev and git, or we could leave them.
RUN apt-get update \
    && apt-get install -y libffi-dev git \
    && rm -rf /var/lib/apt/lists/* \
    # Upgrade pip and install the requirements.
    && pip install --no-cache-dir --upgrade pip \
    && pip install --no-cache-dir -r $FLEX_TEMPLATE_PYTHON_REQUIREMENTS_FILE \
    # Download the requirements to speed up launching the Dataflow job.
    && pip download --no-cache-dir --dest /tmp/dataflow-requirements-cache -r $FLEX_TEMPLATE_PYTHON_REQUIREMENTS_FILE

# Since we already downloaded all the dependencies, there's no need to rebuild everything.
ENV PIP_NO_DEPS=True

作业提交错误

413 Request Entity Too Large/The size of serialized JSON representation of the pipeline exceeds the allowable limit

如果在提交作业时遇到有关 JSON 负载的错误,则表示流水线的 JSON 表示法超过了 20 MB 的请求大小上限。这些错误可能在 Console 或终端窗口中显示为以下消息之一:

  • 413 Request Entity Too Large
  • “流水线的序列化 JSON 表示法的大小超出允许的限额”
  • “无法创建工作流程作业:收到无效的 JSON 负载”
  • “无法创建工作流程作业:请求负载超出允许的限额”

作业的大小与流水线的 JSON 表示法明确关联。流水线越大,意味着请求越大。Dataflow 目前的请求大小上限为 20 MB。

如需估算流水线的 JSON 请求大小,请使用以下选项运行您的流水线:

Java

--dataflowJobFile=< path to output file >

Python

--dataflow_job_file=< path to output file >

此命令会将作业的 JSON 表示写入文件中。您最好根据序列化文件的大小来估算请求大小。由于请求中包含一些其他信息,实际大小将会略大一些。

流水线中的某些情况可能会导致 JSON 表示法超出限额。常见情况包括:

  • 包含大量内存数据的 Create 转换。
  • 大型 DoFn 实例(进行序列化处理后传输给远程工作器)。
  • 作为匿名内部类实例的 DoFn,该实例(可能无意中)引入了大量要序列化的数据。

为了避免这些情况,请考虑重新构造您的流水线。

The job graph is too large. Please try again with a smaller job graph, or split your job into two or more smaller jobs.

您的作业图大小不得超过 10 MB。流水线中的某些情况可能导致作业图超出限额。常见情况包括:

  • 包含大量内存数据的 Create 转换。
  • 大型 DoFn 实例(进行序列化处理后传输给远程工作器)。
  • 作为匿名内部类实例的 DoFn,该实例(可能无意中)引入了大量要序列化的数据。

为了避免这些情况,请考虑重新构造您的流水线。

Total number of BoundedSource objects generated by splitIntoBundles() operation is larger than the allowable limitTotal size of the BoundedSource objects generated by splitIntoBundles() operation is larger than the allowable limit

Java

如果您通过 TextIOAvroIO 或其他一些基于文件的来源读取大量文件,则可能会遇到此错误。特定的限额取决于来源的细节(例如,在 AvroIO.Read 中嵌入架构会允许较少的文件),通常每个流水线中可以有数万个文件。

如果您为流水线创建了自定义数据源,并且数据源的 splitIntoBundles 方法返回了一个序列化后超过 20 MB 的 BoundedSource 对象的列表,则您可能也会遇到此错误。

自定义来源的 splitIntoBundles() 操作生成的 BoundedSource 对象总大小的允许限额为 20 MB。您可以通过修改自定义 BoundedSource 子类来解决这一限制,以便生成的 BoundedSource 对象的总大小低于 20 MB 限额。例如,您的数据源最初可能会生成较少的拆分,并依赖动态工作负载再平衡来按需进一步拆分输入。

“SDK 流水线选项或暂存文件列表超出大小限制。请确保其各自的长度不超过 256K 字节,总计不超过 512K 字节。”

由于超出了 Google Compute Engine 元数据限制,无法启动流水线。这些限制无法更改。Dataflow 为流水线选项使用 Compute Engine 元数据。Compute Engine 自定义元数据限制中记录了此限制。

暂存 jar 文件过多可能会导致 JSON 表示法超出限制。

如何查找完整的流水线选项及其长度?如需估算流水线的 JSON 请求大小,请使用以下选项运行您的流水线:

Java

--dataflowJobFile=< path to output file >

Python

--dataflow_job_file=< path to output file >

上述输出文件的大小必须小于 256K 字节。错误消息中的 512K 字节是指上述输出文件和 Compute Engine 虚拟机实例的自定义元数据选项的总大小。虚拟机实例的自定义元数据选项的粗略估计值可以根据项目中正在运行的 Dataflow 作业确定。选择任何正在运行的 Dataflow 作业,获取虚拟机实例,然后导航到 Compute Engine 虚拟机实例详情页面,以检查自定义元数据部分。自定义元数据和上述文件的总长度应小于 512K 字节。由于此作业的虚拟机未启动,因此无法对失败的作业进行准确估计。

如果 jar 列表达到 256K 字节的限制,请进行查看并减少任何不必要的 jar。如果该列表仍然太大,请尝试使用超级 jar 执行 Dataflow 作业。

本文档的 Cloud Functions 函数部分介绍了有关如何创建和使用超级 jar 的示例

Startup of the worker pool in zone $ZONE failed to bring up any of the desired $N workers. The project quota may have been exceeded or access control policies may be preventing the operation; review the Cloud Logging 'VM Instance' log for diagnostics.

此错误有两个可能的原因:

  • 您可能已超出创建 Dataflow 工作器所依赖的其中一个 Compute Engine 配额。
  • 您的组织已设置限制,以禁止虚拟机实例创建过程的某些方面,例如使用帐号或以区域为目标。

要排查此问题,请执行以下操作:

查看虚拟机实例日志

  1. 转到 Cloud Logging 查看器
  2. 已审核的资源下拉列表中,选择虚拟机实例
  3. 所有日志下拉列表中,选择 compute.googleapis.com/activity_log
  4. 扫描日志以查找与虚拟机实例创建失败相关的任何条目。

检查 Compute Engine 配额的使用情况

  1. 在本地机器命令行上或在 Cloud Shell 中,运行以下命令以查看 Compute Engine 资源使用情况与目标区域的 Dataflow 配额的对比情况:

    gcloud compute regions describe [REGION]

  2. 查看以下资源的结果,了解是否有任何资源超出配额:

    • CPUS
    • DISKS_TOTAL_GB
    • IN_USE_ADDRESSES
    • INSTANCE_GROUPS
    • INSTANCE_GROUP_MANAGERS
    • INSTANCES
  3. 如果需要,请申请更改配额

查看组织政策限制

  1. 转到“组织政策”页面
  2. 查看可能会限制以下行为的限制:限制为您使用的帐号(默认为 Dataflow 服务帐号)或在您设为目标的区域中创建虚拟机实例。

工作器日志

“处理卡在/操作运行在步骤 <step_id> 中至少 <time_interval> 且未输出,或在 <stack_trace> 处进入完成状态”

如果 Dataflow 执行 DoFn 的时间超过 <time_interval> 中指定的时间且未返回,则会显示此消息。

此错误有两个可能的原因:

  • 您的 DoFn 代码运行很慢,或在等待一些缓慢的外部操作完成。
  • 您的 DoFn 代码可能被卡住、出现死锁或运行异常缓慢,难以完成处理。

要确定是哪种情况,请展开 Cloud Monitoring 日志条目以查看堆栈轨迹。查找表明 DoFn 代码卡住或遇到其他问题的消息。如果不存在,则可能是 DoFn 代码的执行速度有问题。请考虑使用 Cloud Profiler 或其他工具来调查代码的性能。

如果您的流水线是在 Java 虚拟机上构建的(使用 Java 或 Scala),您可以进一步调查卡住代码的原因;按照以下步骤对整个 JVM(不仅仅是卡住的线程)进行完整的线程转储:

  1. 记下日志条目中的工作器名称。
  2. 在 Cloud Console 的 Compute Engine 部分,使用您记下的工作器名称来寻找 Compute Engine 实例。
  3. 通过 SSH 登录到具有该名称的实例。
  4. 运行以下命令:

    curl http://localhost:8081/threadz
    

重排键过大异常

如果您遇到指示重排键过大的异常,则意味着在应用相应的编码器后,发送到特定 (Co-)GroupByKey 的序列化键太大。Dataflow 对序列化重排键有限制。请考虑减小键的大小或使用更节省空间的编码器。

KeyCommitTooLargeException

在流处理场景中,这可能是由于不使用 Combine 转换将大量数据分组,或者从单个输入元素产生大量数据导致的。以下策略可以降低发生此异常的几率:

  • 确保处理单个元素不会导致输出或状态修改超出限制。
  • 如果一个键下分组了多个元素,请考虑增加键空间以减少每个键下分组的元素。
  • 如果某个键的元素在短时间内以高频率发出,这可能会导致在窗口中产生该键的大量事件。请重新编写流水线以检测此类键,并仅发出指明相应键在该窗口中频繁出现的输出。
  • 确保将次线性空间 Combine 转换用于交换和关联操作。如果一个组合器不能减少空间,请不要使用它。例如,没有必要使用只是将字符串连接起来的字符串组合器。

RPC 超时异常、DEADLINE_EXCEEDED 异常或 Server Unresponsive 错误

如果在作业运行时遇到 RPC 超时、DEADLINE_EXCEEDED 异常或 Server Unresponsive 错误,则通常表示存在以下两个问题之一:

  • 用于您的作业的 VPC 网络可能缺少防火墙规则。防火墙规则需要允许您在流水线选项中指定的 VPC 网络中虚拟机之间的所有 TCP 流量。如需了解详情,请参阅指定网络和子网

  • 您的作业可能处于随机编排受限状态。考虑执行以下操作流程之一或结合使用其中多个操作流程:

    Java

    • 如果作业未使用基于服务的 Shuffle,请设置 --experiments=shuffle_mode=service 以切换到使用基于服务的 Dataflow Shuffle。如需了解详情和可用性,请参阅 Dataflow Shuffle
    • 添加更多工作器。在运行流水线时尝试设置具有更高值的 --numWorkers
    • 增加工作器挂接的磁盘的大小。在运行流水线时尝试设置具有更高值的 --diskSizeGb
    • 使用支持 SSD 的永久性磁盘。在运行流水线时尝试设置 --workerDiskType="compute.googleapis.com/projects/<project>/zones/<zone>/diskTypes/pd-ssd"

    Python

    • 如果作业未使用基于服务的 Shuffle,请设置 --experiments=shuffle_mode=service 以切换到使用基于服务的 Dataflow Shuffle。如需了解详情和可用性,请参阅 Dataflow Shuffle
    • 添加更多工作器。在运行流水线时尝试设置具有更高值的 --num_workers
    • 增加工作器挂接的磁盘的大小。在运行流水线时尝试设置具有更高值的 --disk_size_gb
    • 使用支持 SSD 的永久性磁盘。在运行流水线时尝试设置 --worker_disk_type="compute.googleapis.com/projects/<project>/zones/<zone>/diskTypes/pd-ssd"

Java 工作器对 Python DoFn 的调用失败,并显示错误 <error message>

如果在 Python 中实现的 DoFn 失败并抛出异常,则会显示相关的错误消息。

展开 Cloud Monitoring 错误日志条目并查看错误消息和回溯。它会显示失败的代码,以便您根据需要进行更正。如果您确定这是 Apache Beam 或 Dataflow 中的错误,请报告错误

设备上已没有剩余空间

当某个作业耗尽磁盘空间时,您可能会在工作器日志中看到 No space left on device 错误。

如果作业在运行时下载大型依赖项、使用大型自定义容器或将大量临时数据写入本地磁盘,则工作器永久性存储空间的可用空间可能会耗尽。

使用 Dataflow Shuffle 时,Dataflow 会设置较低的默认磁盘大小。因此,来自基于工作器的 shuffle 操作的作业也可能会出现此错误。

如果每秒记录的条目数超过 50 个,则工作器启动磁盘也可能填满。

如需查看与单个工作器关联的磁盘资源,请查找与作业关联的工作器虚拟机的虚拟机实例详情。部分磁盘空间将供操作系统、二进制文件、日志和容器使用。

要增加永久性磁盘或启动磁盘空间,请调整磁盘大小流水线选项

您可以使用 Cloud Monitoring 跟踪工作器虚拟机实例上的磁盘空间使用情况。如需了解如何进行此设置,请参阅从 Monitoring 代理接收工作器虚拟机指标

您还可以通过在工作器虚拟机实例上查看串行端口输出并查找类似于“无法打开系统日志:设备上已没有剩余空间”的消息来查找启动磁盘空间问题。如果您有大量工作器虚拟机实例,则您可能希望创建一个脚本,以便同时对所有这些实例运行 gcloud compute instances get-serial-port-output 并查看这些实例的输出。

如需了解详情,请参阅永久性磁盘资源

EOFError:编组数据太短

当 Python 流水线工作器的磁盘空间不足时,有时会发生此错误。请参阅设备上已没有剩余空间

Shuffler 日志中出现 Bad request 警告

在执行 Dataflow 作业期间,Cloud Monitoring 日志可能会显示一系列警告,如下所示:

Unable to update setup work item <step_id> error: generic::invalid_argument: Http(400) Bad Request
Update range task returned 'invalid argument'. Assuming lost lease for work with id <lease_id>
with expiration time: <timestamp>, now: <timestamp>. Full status: generic::invalid_argument: Http(400) Bad Request

出现“错误请求”警告的原因是,工作器状态信息因处理延迟而过时或不同步。通常情况下,尽管存在这些“错误请求”警告,您的 Dataflow 作业仍会成功。如果出现这种情况,请忽略此类警告。

在...检测到热键 <hot-key-name>

这些错误标识数据中的热键。热键是具有很多元素并对流水线性能造成不利影响的键。这些键会限制 Dataflow 并行处理元素的能力,从而增加执行时间。

要记录热键的存在,请使用热键流水线选项

请检查您的数据分布是否均匀。如果某个键具有异常多的值,请考虑执行以下操作流程:

Python 自定义容器流水线失败,并显示 SystemError:未知操作码

如果您在提交作业后立即遇到意外的 Python 错误 SystemError: unknown opcode,且堆栈轨迹包含 apache_beam/internal/pickler.py,请验证您在本地使用的 Python 版本与容器映像中的版本匹配(主要版本和次要版本均匹配)。补丁程序版本不同(如 3.6.7 与 3.6.8)不会导致兼容性问题,但次要版本不同(例如 3.6.8 与 3.8.2)可能导致流水线失败。

输入和输出错误

I/O 指标图表使用规范错误代码。如果这些错误代码在您的来源和接收器中仍然存在,请参阅以下列表,了解潜在原因和可以执行的操作。

  • RESOURCE_EXHAUSTED。项目可能已用完来源或接收器使用的服务的资源配额

    如果错误偶尔发生,或者在每秒请求次数图表指示发出了大量请求时出现,则可能表示达到了 API 速率限制配额,需要增加配额。

  • DEADLINE_EXCEEDED。来源或接收器在读取或写入大批量数据时可能已超时。请检查延迟时间图表和工作器日志。如果错误仍然存在,请与支持团队联系

  • INVALID_ARGUMENT。为来源或接收器指定的参数可能格式不正确(例如 Pub/Sub 主题)。检查来源或接收器的配置,并检查工作器日志。

  • FAILED_PRECONDITION。检查来源或接收器的配置,并检查工作器日志。这也可能表示存在错误。

  • OUT_OF_RANGE。检查来源或接收器使用的资源(例如 Pub/Sub 主题或订阅)是否存在。

  • UNAUTHENTICATED。检查 Dataflow 服务帐号是否对特定服务拥有 Identity and Access Management 权限,并且已为项目启用相关的 API

  • PERMISSION_DENIED。检查 Dataflow 服务帐号是否对特定服务拥有 Identity and Access Management 权限,并且已为项目启用相关的 API

  • NOT_FOUND。检查来源或接收器使用的实体(例如 Pub/Sub 主题或订阅)是否存在。

  • ABORTED。服务可能无法正确处理来源或接收器读取或写入数据的尝试。如果错误仍然存在,请与支持团队联系

  • ALREADY_EXISTS。I/O 可能正在尝试创建已存在的实体(例如 Pub/Sub 主题或订阅)。如果错误仍然存在,请与支持团队联系

  • CANCELLED。如果 Dataflow 工作器关闭,或者来源或接收器逻辑有意决定取消读取或写入数据尝试,则可能会发生这种情况。

  • DATALOSS。指示发生了不可恢复的数据丢失或损坏。您可能希望为来源创建新数据集并重新运行 Dataflow 作业。

    您还可以查看是否有任何备份和恢复说明可用于底层 Google Cloud 服务。

  • UNKNOWN。服务可能已关闭。如需了解详情,请在 Cloud 状态信息中心上查看是否有更新。

  • INTERNAL。服务可能已关闭。如需了解详情,请在 Cloud 状态信息中心上查看是否有更新。

  • UNAVAILABLE。服务可能已关闭。如需了解详情,请在 Cloud 状态信息中心上查看是否有更新。

  • UNIMPLEMENTED。来源或接收器已尝试通过无效的方式使用该服务。您的流水线可能配置有误。如果错误仍然存在,请与支持团队联系

工作器启动错误

日志类型 dataflow.googleapis.com/worker-startupdataflow.googleapis.com/harness-startupdataflow.googleapis.com/kubelet 中的错误表明作业存在配置问题。还可能表示存在导致正常日志记录路径无法正常使用的条件。

NoClassDefFound 错误

这些错误也可能是 Unable to initialize main class [...] 形式。NoClassDefFound 错误表明上传到 Dataflow 服务的 JAR 文件不包含运行 Dataflow 所需的类。通常在 --filesToStage PipelineOption 被替换以及某些必需的 JAR 或类文件被省略时会发生此错误。

映像拉取请求失败,发生错误

此错误表示工作器无法启动,因为工作器无法拉取 Docker 容器映像。如果自定义 SDK 容器映像网址不正确,或者工作器缺少凭据或对远程映像的网络访问权限,则可能会发生此错误。

如果您为作业使用自定义容器映像,请验证映像网址正确、具有有效的标记或摘要,并且 Dataflow 工作器可以访问该映像。

通过从未经身份验证的机器运行 docker pull $image,验证可以在本地拉取公共映像。

私有映像或私有工作器有额外的考虑事项。

  • Dataflow 仅支持 Container Registry 上托管的私有容器映像。如果您使用 Container Registry 托管容器映像,则默认 Google Cloud 服务帐号可以访问同一项目中的映像。如果您使用的映像所在的项目与用于运行 Google Cloud 作业的项目不同,请确保为默认 Google Cloud 服务帐号配置访问权限控制
  • 如果使用共享 Virtual Private Cloud (VPC),请确保工作器可以访问自定义容器代码库主机。
  • 使用 ssh 连接到正在运行的作业工作器虚拟机,并运行 docker pull $image 以直接确认工作器已正确配置。

如果工作器由于此错误而多次失败,并且作业未启动任何工作,则作业可能会失败,并显示 Job appears to be stuck. ... 之类的错误。如果您在作业运行时移除了对映像的访问权限(通过移除映像本身、撤消 Dataflow 工作器服务帐号凭据或撤销映像的互联网访问权限),则 Dataflow 将仅记录错误而不执行操作,从而使作业失败。Dataflow 还会避免使长时间运行的流式流水线失败,以避免丢失流水线状态。

其他错误可能是由代码库配额问题或服务中断造成的。如果您遇到拉取公共映像时超出 Docker Hub 配额或常规第三方代码库服务中断问题,请考虑使用 Container Registry 作为映像代码库。

同步 pod 时出错 ...“StartContainer”失败

此错误表示工作器 Docker 容器未能启动。此错误通常在某个容器在启动时持续崩溃时发生。

如果容器崩溃,请查找说明工作器启动、harness 启动或 Docker 日志中故障的错误消息。Python 作业的常见启动崩溃情况是依赖项问题导致的 pip 安装错误 (pip install failed with error...)。这可能包括不兼容的指定依赖项或导致指定代码库无法访问的网络问题。容器中安装的 Apache Beam Python SDK 应与启动作业所用的 SDK 相同。

如果在长时间运行的作业期间无法拉取容器映像,也可能会出现此错误。如需了解详情,请参阅“映像拉取请求失败,发生错误”

“Java 运行时环境检测到严重错误”

这表明流水线使用 Java 本地接口 (JNI) 运行非 Java 代码,并且该代码或 JNI 绑定存在错误。

日志

我没有看到任何日志

如果您没有看到作业的任何日志,请从所有 Cloud Logging 日志路由器接收器中移除任何包含 resource.type="dataflow_step" 的排除过滤器。

转到日志路由器

如需详细了解如何移除日志排除项,请参阅移除排除项指南。

建议

较高的 Streaming Engine 转移作业配额用量

使用 Streaming Engine 的作业与 Streaming Engine 之间的数据转移量具有区域限制。请务必保持在限制之内,因为达到限制可能会影响作业性能。此外,减少转移的字节数可能会降低结算费用。

如需查看您项目的限制,请参阅配额和限制中的说明。如需查看作业的当前使用量,请点击此 Metrics Explorer 链接。如有必要,请选择运行作业的项目。然后,将 REGION 替换为您需要的区域,然后点击“运行查询”。

减少用量的建议:

  • 减少 GroupByKey 和 Combine 转换处理的数据量。这可以通过减少传递的元素数量或省略不必要的字段来实现。
  • 更高效地编码数据以减少占用的空间。在某些情况下,这可能会增加工作器上的 CPU 利用率。

    • 对于自定义数据类型,默认的编码器可能效率低下(Java 中为 SerializableCoder,Python 中为 PickleCoder)。请尝试为自定义类型选择更高效的默认编码器或具有架构的 PCollection。

      如需详细了解编码器以及如何指定它们,请参阅 Beam 编程指南中的数据编码章节。如需详细了解具有架构的 PCollection,请参阅架构章节

    • 对于较大的元素,使用压缩可能会有所帮助。

  • 减少大型状态读取。例如,如果流水线具有足够大的 BagState,将需要在提取它时从 Streaming Engine 转移。

    • 请尝试减小状态大小。
    • 请尝试降低状态提取频率。
    • 状态与特定键和窗口相关联。可以使用非全局数据选取来限制状态大小。

    如需详细了解状态,请参阅 Beam 编程指南中的状态和计时器章节

自动扩缩:可以增加 maxNumWorkers

Dataflow 检测到作业使用的工作器数量已达上限 maxNumWorkers(或 max_num_workers),如果提高此上限,可以使用更多工作器。例如,对于 maxNumWorkers 设置为 50 的作业,如果它使用了 50 个工作器并且平均工作器 CPU 利用率超过 80%,系统将提供此建议。

通常,增加 maxNumWorkers 可以提高流水线吞吐量:批量流水线可以在更短的时间内完成,而流式流水线可以处理更大的数据峰值,每秒处理更多元素。但是,这可能会增加费用(请参阅工作器资源价格)。如需详细了解自动扩缩算法的工作原理及其配置方法,请参阅自动扩缩指南

建议:

  • 请尝试增加或移除 maxNumWorkers 流水线选项。如果没有此选项,Dataflow 将使用自动扩缩指南中列出的默认值。
  • 如果流水线性能足够,您可以不执行任何操作。
    • 对于批量流水线,请确保总运行时间符合您的要求。
    • 对于流式流水线,请在作业页面的“作业指标”标签页中查看数据新鲜度图表。请确保数据新鲜度没有持续增加,并且值在可接受的范围内。

检测到高扇出

Dataflow 检测到作业具有一个或多个“高扇出”转换。当具有高输出到输入元素计数比率的 ParDo 与后续 ParDo 融合时,就会发生此情况。在这种情况下,第二个 ParDo 会在第一个 ParDo 后依序运行。这会使给定输入的所有输出元素都进入同一个工作器,从而降低并行性和性能。

建议:

  • 插入一个 GroupByKey 并在第一个 ParDo 之后取消分组。Dataflow 服务永远不会融合汇总过程中的 ParDo 操作。
  • 将中间 PCollection 作为辅助输入传递到另一个 ParDo。Dataflow 服务始终会将辅助输入具体化。
  • 插入“重排”步骤。重排可防止融合,为数据添加检查点并重新配置数据选取策略,以避免丢弃数据。虽然在 Apache Beam 文档中重排被标记为已弃用,Dataflow 仍然支持重排(请注意,重排数据可能会增加运行流水线的费用)。