对 Flex 模板进行问题排查

本页面介绍使用 Dataflow 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. 外部 IP 地址已停用,并且虚拟机无法连接到 Google API 和服务使用的外部 IP 地址集。
  4. 创建图表的程序完成所需时间过长。
  5. 流水线选项被覆盖。
  6. (仅限 Python)requirements.txt 文件存在问题。
  7. 发生暂时性错误。

要解决此问题,请首先检查作业日志并重试,看看是否存在暂时性错误。如果这些步骤无法解决问题,请尝试以下问题排查步骤。

验证 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 映像。

配置专用 Google 访问通道

如果外部 IP 地址已停用,您需要允许 Compute Engine 虚拟机连接到 Google API 和服务使用的外部 IP 地址集。在虚拟机网络接口使用的子网上启用专用 Google 访问通道。

有关配置详情,请参阅配置专用 Google 访问通道

默认情况下,当 Compute Engine 虚拟机缺少分配给其网络接口的外部 IP 地址时,它只能将数据包发送到其他内部 IP 地址目的地。

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

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

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

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

直接启动(不使用模板)的流水线没有这些限制。因此,如果流水线直接启动时可正常运行,但作为模板时却无法正常运行,则使用模板可能是根本原因。查找模板中的问题并修复模板可能会解决问题。

验证是否禁用了必需的流水线选项

使用 Flex 模板时,您可以在流水线初始化期间配置部分(但不是全部)流水线选项。如需了解详情,请参阅本文档中的读取作业文件失败部分。

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

如果您的 Dockerfile 包含具有 apache-beam[gcp]requirements.txt,请将其从文件中移除并单独安装。以下命令演示了如何完成此步骤:

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

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

使用 Python 时轮询超时

如果您使用 Flex 模板和 Python 运行 Dataflow 作业,则作业可能会排队一段时间,运行失败,然后显示以下错误:

Timeout in polling

用于安装所需依赖项的 requirements.txt 文件会导致错误。当您启动 Dataflow 作业时,系统会先暂存所有依赖项,以使这些文件可供工作器虚拟机访问。此过程涉及下载和编译 requirements.txt 文件中的每个直接和间接依赖项。某些依赖项可能需要数分钟才能完成编译。值得注意的是,PyArrow 可能需要一些时间才能完成编译。PyArrow 是 Apache Beam 和大多数 Cloud 客户端库使用的间接依赖项。

如需优化作业的性能,请使用 Dockerfile 或自定义容器预封装依赖项。如需了解详情,请参阅“配置 Flex 模板”中的软件包依赖项

作业启动失败

以下部分介绍导致作业启动失败的常见错误以及解决或排查错误问题的步骤。

早期启动问题

当模板启动过程在早期阶段失败时,常规 Flex 模板日志可能不可用。如需调查启动问题,请为模板启动器虚拟机启用串行端口日志记录

如需为 Java 模板启用日志记录,请将 enableLauncherVmSerialPortLogging 选项设置为 true。如需为 Python 和 Go 模板启用日志记录,请将 enable_launcher_vm_serial_port_logging 选项设置为 true。在 Google Cloud 控制台中,该参数在可选参数中列为启用启动器虚拟机串行端口日志记录

您可以在 Cloud Logging 中查看模板启动器虚拟机的串行端口输出日志。如需查找特定启动器虚拟机的日志,请使用查询 resource.type="gce_instance" "launcher-number",其中 numberYYYMMDD 格式的当前日期开头。

组织政策可能会禁止您启用串行端口输出日志记录功能。

读取作业文件失败

当您尝试从 Flex 模板运行作业时,作业可能会失败,并显示以下错误之一:

Failed to read the job file : gs://dataflow-staging-REGION-PROJECT_ID/staging/template_launches/TIMESTAMP/job_object with error message: ...: Unable to open template file

或:

Failed to read the result file : gs://BUCKET_NAME with error message: (ERROR_NUMBER): Unable to open template file: gs://BUCKET_NAME

如果必要的流水线初始化选项被覆盖,便会出现此错误。使用 Flex 模板时,您可以在流水线初始化期间配置部分(但不是全部)流水线选项。如果 Flex 模板所需的命令行参数被覆盖,作业可能会忽略、替换或舍弃模板启动器传递的流水线选项。此外,作业本身可能会无法启动,或者系统可能会启动未使用 Flex 模板的作业。

为避免此问题,在流水线初始化期间,请勿更改用户代码或 metadata.json 文件中的以下流水线选项

Java

  • runner
  • project
  • jobName
  • templateLocation
  • region

Python

  • runner
  • project
  • job_name
  • template_location
  • region

Go

  • runner
  • project
  • job_name
  • template_location
  • region

对资源的权限被拒绝

尝试从 Flex 模板运行作业时,作业可能会失败,并报告以下错误:

Permission "MISSING_PERMISSION" denied on resource "projects/PROJECT_ID/locations/REGION/repositories/REPOSITORY_NAME" (or it may not exist).

当使用的服务账号无权访问运行 Flex 模板所需的资源时,会发生此错误。

为避免此问题,请验证服务账号是否具有所需权限。根据需要调整服务账号权限。

提供了标志但未定义

当您尝试使用 worker_machine_type 流水线选项运行 Go Flex 模板时,流水线会失败,并显示以下错误:

flag provided but not defined: -machine_type

此错误是由 Apache Beam Go SDK 2.47.0 版及更低版本中的已知问题引起的。如需解决此问题,请升级到 Apache Beam Go 2.48.0 版或更高版本。

Flex 模板启动器延迟

提交 Flex 模板作业时,作业请求会进入 Spanner 队列。模板启动器会从 Spanner 队列中获取作业,然后运行该模板。如果 Spanner 存在消息积压的情况,则您提交作业时间与作业启动时间之间可能会发生明显延迟。

如需解决此问题,请从其他区域启动 Flex 模板。

模板参数无效

当您尝试使用 gcloud CLI 运行使用 Google 提供的模板的作业时,会发生以下错误:

ERROR: (gcloud.beta.dataflow.flex-template.run) INVALID_ARGUMENT: The template
parameters are invalid. Details: defaultSdkHarnessLogLevel: Unrecognized
parameter defaultWorkerLogLevel: Unrecognized parameter

发生此错误是因为某些 Google 提供的模板不支持 defaultSdkHarnessLogdefaultWorkerLog 选项。

如需解决此问题,请将模板规范文件复制到 Cloud Storage 存储桶中。将以下更多参数添加到该文件中。

"metadata": {
    ...
    "parameters": [
      ...,
      {
        "name": "defaultSdkHarnessLogLevel",
        "isOptional": true,
        "paramType": "TEXT"
      },
      {
        "name": "defaultWorkerLogLevel",
        "isOptional": true,
        "paramType": "TEXT"
      }
    ]
  }

对模板文件进行此更改后,请使用以下命令运行模板。

--template-file-gcs-location=gs://BUCKET_NAME/FILENAME

替换以下值:

  • BUCKET_NAME:Cloud Storage 存储桶的名称
  • FILENAME:模板规范文件的名称

Flex 模板启动器日志显示错误的严重级别

自定义 Flex 模板启动失败时,日志文件中显示以下严重级别为 ERROR 的消息:

ERROR: Error occurred in the launcher container: Template launch failed. See console logs.

启动失败的根本原因通常显示在日志中严重级别为 INFO 的消息之前。虽然此日志级别可能不正确,但符合预期,因为 Flex 模板启动器无法从 Apache Beam 应用生成的日志消息中提取严重级别详细信息。

如果您希望在启动器日志中查看每条消息的正确严重级别,请将模板配置为生成 JSON 格式(而不是纯文本)的日志。通过此配置,模板启动器可以提取正确的日志消息严重级别。使用以下消息结构:

{
  "message": "The original log message",
  "severity": "DEBUG/INFO/WARN/ERROR"
}

在 Java 中,您可以将 Logback 日志记录器与自定义 JSON 附加器实现结合使用。如需了解详情,请参阅 GitHub 中的 Logback 示例配置JSON 附加器示例代码

此问题仅会影响流水线启动时由 Flex 模板启动器生成的日志。如果启动成功且流水线正在运行,Dataflow 工作器生成的日志会具有适当严重级别。

Google 提供的模板在作业启动期间会显示正确的严重级别,因为 Google 提供的模板使用此 JSON 日志记录方法。