常见错误指南

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

作业消息:

作业提交错误:

工作器日志 (Stackdriver):

作业消息

“这项作业失败了,因为某个工作项失败了 4 次。”

如果由于代码抛出异常或崩溃,某个操作导致工作器代码失败四次,Dataflow 将标示该作业失败,并显示 a work item failed 4 times 消息。

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

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

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

作业曾经可以运行,现在却失败了,并显示“暂存的软件包...无法访问”

确认用于暂存的 Cloud Storage 存储分区没有会导致暂存软件包被删除的 TTL 设置

作业提交错误

“413 请求实体过大”/“流水线的序列化 JSON 表示法的大小超出允许的限额”

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

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

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

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

Java:SDK 2.x

--dataflowJobFile=< path to output file >

Python

--dataflow_job_file=< path to output file >

Java:SDK 1.x

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

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

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

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

“作业图过大。请使用较小的作业图重试,或将作业拆分成两个或更多较小的作业。”

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

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

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

“splitIntoBundles() 操作生成的 BoundedSource 对象总数大于允许的限额”或“splitIntoBundles() 操作生成的 BoundedSource 对象的总字节数大于允许的限额”。

Java:SDK 2.x

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

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

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

Java:SDK 1.x

工作器日志 (Stackdriver)

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

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

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

  • 您的 DoFn 代码运行很慢,或在等待一些缓慢的外部操作完成。在这种情况下,您可以忽略该警告。
  • 您的 DoFn 代码可能被卡住、出现死锁或运行异常缓慢,难以完成处理。如果您确定这是您遇到的情况,请展开 Stackdriver 日志条目以查看卡住代码的堆栈轨迹。

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

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

    curl http://localhost:8081/threadz
        

RPC 超时异常,“DEADLINE_EXCEEDED”异常或“服务器无响应”错误

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

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

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

    Java:SDK 2.x

    • 添加更多工作器。在运行流水线时尝试设置具有更高值的 --numWorkers
    • 增加工作器挂接的磁盘的大小。在运行流水线时尝试设置具有更高值的 --diskSizeGb
    • 使用支持 SSD 的永久性磁盘。在运行流水线时尝试设置 --workerDiskType="compute.googleapis.com/projects/<project>/zones/<zone>/diskTypes/pd-ssd"

    Python

    • 添加更多工作器。在运行流水线时尝试设置具有更高值的 --num_workers
    • 增加工作器挂接的磁盘的大小。在运行流水线时尝试设置具有更高值的 --disk_size_gb
    • 使用支持 SSD 的永久性磁盘。在运行流水线时尝试设置 --worker_disk_type="compute.googleapis.com/projects/<project>/zones/<zone>/diskTypes/pd-ssd"

    Java:SDK 1.x


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

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

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

设备上已没有剩余空间

如果某项作业整理大量数据或将临时数据写入本地磁盘,则工作器永久性存储空间可能会耗尽可用空间。

如果您看到一条消息,通知您设备上已没有剩余空间,请通过设置相关流水线选项来增加工作器的永久性磁盘大小。 对于 Java 作业,请使用标志 --diskSizeGb。对于 Python 作业,请使用 --disk_size_gb

磁盘空间错误,例如“RESOURCE_EXHAUSTED:IO 错误:磁盘上已没有剩余空间”

这些错误通常表示您没有分配足够的本地磁盘空间来处理您的作业。如果使用默认设置运行作业,则作业将在 3 个工作器上运行,每个工作器具有 25 GB 的本地磁盘空间,并且不会自动扩缩。请考虑修改默认设置,以增加可用于作业的工作器数量、增加每个工作器的默认磁盘大小或启用自动扩缩

Shuffler 日志中出现“错误请求”警告

在执行 Dataflow 作业期间,Stackdriver 日志可能会显示一系列警告,类似以下内容:

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 作业仍会成功。如果出现这种情况,请忽略此类警告。

在步骤 <step_id> 中检测到时长为 <time_interval>s 的热键

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

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