排查 Spanner 截止时间超出错误

本页面简要介绍了 Spanner 超出期限的错误: 问题的定义、出现原因、如何进行问题排查和解决。

访问 Spanner API 时,请求可能会由于以下原因而失败: DEADLINE_EXCEEDED 个错误。此错误表示未在配置的超时期限内收到响应。

超出时限错误可能由许多不同的原因导致,例如 Spanner 实例过载、未优化的架构或未优化的查询。本页面介绍了有关超出截止期限错误的常见情况 并指导您如何调查和解决这些问题。

Spanner 的截止期限和重试哲学

Spanner 的截止期限和重试理念与许多其他系统不同。在 Spanner 中,您应指定超时截止期限,作为响应有效的最长时间。人为设置一个 立即重试同一操作的截止期限较短 推荐,因为这会导致操作无法完成。在这种情况下,不建议采用以下策略和操作;它们适得其反,会破坏 Spanner 的内部重试行为:

  • 设置的截止期限过短。也就是说,操作 能够灵活应对偶尔的尾延迟时间增加,无法在该时间之前完成 超时。请改为设置一个截止期限,即响应有效的最长时间。

  • 设置太长的截止期限,并在 超过截止时间。这会导致重试和每次尝试都浪费工作。总体而言,这可能会给您的实例带来大量额外负载。

什么是“已超出截止日期”错误?

当您使用其中一个 Spanner 客户端库时, 底层 gRPC 层负责通信、编组、解组, 和最后期限的强制执行截止期限可让应用指定 愿意等待请求完成,然后再终止该请求 错误。

超时配置指南演示了 如何在每个受支持的 Spanner 中指定截止期限(或超时) 客户端库。Spanner 客户端库使用默认超时 和重试以下配置文件中定义的政策设置:

如需详细了解 gRPC 截止期限,请参阅 gRPC 和截止期限

如何调查和解决常见的截止期限已过错误

对于以下问题类型,您可能会遇到 DEADLINE_EXCEEDED 错误:

Data Access API 问题

必须为您的 Cloud Spanner 实例 避免数据访问 API 问题。以下部分介绍了如何调查和解决不同的数据访问 API 问题。

检查 Spanner 实例的 CPU 负载

当 CPU 利用率超过建议的健康阈值时,请求延迟时间可能会大幅增加。您可以在 Google Cloud 控制台中提供的监控控制台中查看 Spanner 的 CPU 利用率。您还可以根据实例的 CPU 利用率创建提醒

解决方法

如需了解降低实例 CPU 利用率的步骤,请参阅降低 CPU 利用率

查看请求的端到端延迟时间明细

当请求从客户端传输到 Spanner 服务器并返回时, 还需要进行多个网络跃点:从客户端库到 Google Front End (GFE);从 GFE 到 Spanner API 前端; 最后从 Spanner API 前端 Spanner 数据库。如果在上述任一阶段出现网络问题,您可能会看到超出截止期限的错误。

您可以捕获每个阶段的延迟时间。如需了解详情,请参阅 Spanner 请求中的延迟时间点。如需了解 Spanner 中出现延迟的时间点,请参阅确定 Spanner 中出现延迟的时间点

解决方法

获取延迟时间明细后,您可以使用指标诊断延迟时间,了解延迟时间出现的原因并找到解决方案。

Data API 问题

Spanner 的 Data API 的某些非最佳使用模式可能会导致超出截止期限的错误。本部分提供了有关如何检查这些非最佳使用模式的指南。

检查耗用高昂资源的查询

尝试在客户端库中运行在配置的超时截止期限内无法执行的高成本查询可能会导致超出截止期限的错误。一些开销较大的查询示例包括但不限于对大型表执行全表扫描、对多个大型表执行交叉联接,或对非键列使用谓词执行查询(也是全表扫描)。

您可以使用查询统计信息表事务统计信息表检查耗时较长的查询。这些表会显示运行缓慢的查询和事务的相关信息,例如平均读取行数、平均读取字节数、平均扫描行数等。此外,您还可以生成查询执行计划 以进一步检查查询的执行方式。

解决方法

如需优化查询,请参阅 SQL 查询最佳实践指南。 您还可以使用通过前面提到的统计信息表和执行计划获取的数据来优化查询并对数据库进行架构更改。这些最佳实践有助于缩短语句的执行时间,可能有助于消除超出截止期限的错误。

检查锁争用

Spanner 事务需要获取才能提交。以高吞吐量运行的应用可能会导致事务争用相同的资源,从而导致获取锁的等待时间增加,并影响整体性能。这可能会导致任何读取或写入请求超出截止期限。

您可以使用锁定统计信息表并查看以下博文,找出导致读写事务延迟时间过长的原因。在锁定统计信息表中,您可以找到锁定等待时间最长的行键。

锁冲突问题排查指南介绍了如何查找正在访问锁冲突中涉及的列的事务。您还可以使用“使用事务标记进行问题排查”指南了解哪些事务涉及锁定冲突。

解决方法

采取这些最佳实践 以减少锁争用此外,请使用只读事务 ,以避免与写入发生锁冲突。应将读写事务的使用保留给写入或混合读写工作流。按照以下步骤操作应该可以缩短事务执行时间的总延迟时间,并减少超出截止期限的错误。

检查是否有未优化的架构

在为 Spanner 设计最佳数据库架构之前 数据库时,您应该考虑将在数据库内执行的查询 您的数据库。次优架构可能会导致运行时出现性能问题 部分查询。这些性能问题可能会导致请求无法在配置的截止期限内完成。

解决方法

最优的架构设计取决于对数据库进行的读写操作。无论架构具体如何,都应遵循架构设计最佳实践SQL 最佳实践指南。遵循这些指南有助于避免最常见的架构设计问题。导致性能不佳的其他一些根本原因包括:主键的选择、表布局(请参阅使用交错表提高访问速度)、架构设计(请参阅为提高性能优化架构),以及 Spanner 实例中配置的节点的性能(请参阅 Spanner 性能概览)。

检查热点

由于 Spanner 是一个分布式数据库,因此架构设计 都需要考虑热点问题例如,为单调 增加列数将限制 Spanner 的拆分数量 来均匀分配工作负载这些瓶颈可能会导致超时。此外,您还可以使用 Key Visualizer 排查热点导致的性能问题。

解决方法

请参阅上一部分检查是否存在未经优化的分辨率 架构。重新设计 数据库架构并使用交错索引 以避免可能引起热点的索引。如果按照上述步骤 如需缓解此问题,请参阅选择主键以防止出现热点指南。 最后,避免不理想的流量模式,例如大范围读取, 防止基于负载的拆分

检查是否存在配置错误的超时

客户端库为 Spanner。不过,这些默认配置可能需要根据您的特定工作负载进行调整。建议您观察查询费用并调整截止期限,以适应您的特定用例。

解决方法

超时的默认设置适用于大多数用例。用户可以 覆盖这些配置(请参阅自定义超时和重试指南), 但不建议使用比默认超时更激进的超时值。 如果您决定更改超时,请将其设置为应用等待结果的实际时间。您可以尝试配置较长的超时,但切勿将超时设置为短于应用等待的实际时间,因为这会导致该操作的重试频率更高。

Admin API 问题

与数据 API 请求相比,Admin API 请求是一项开销较高的操作。CreateInstanceCreateDatabaseCreateBackups 等管理员请求可以 需要几秒钟的时间才能返回响应。Spanner 客户端库为实例数据库管理员请求设置了 60 分钟的截止期限。这是为了确保服务器有机会完成 请求,然后再重试或失败。

解决方法

如果您使用 Google Spanner 客户端库访问管理员 API,请确保客户端库已更新并使用最新版本。如果您要通过自己创建的客户端库直接访问 Spanner API,请确保您为实例数据库管理员请求设置的截止期限不比默认设置(60 分钟)更短。

Google Cloud 控制台问题

从 Google Cloud 控制台 Spanner Studio 页面发出的查询不得超过 5 分钟。如果您创建的查询运行时间超过 5 分钟,您会看到以下错误消息:

“Google Cloud 控制台的截止时间已过”错误消息的屏幕截图

后端将取消失败的查询,事务可能会回滚 (如果需要的话)。

解决方法

您可以使用 SQL 查询最佳实践指南重写该查询。

Dataflow 问题

在 Apache Beam 中,读取操作的默认超时配置为 2 小时,提交操作的默认超时配置为 15 秒。与独立客户端库截止期限超时相比,这些配置允许更长时间的操作。不过, 但当工作项执行时, 过大。如有必要,您可以自定义 Apache Beam 提交 超时配置。

解决方法

如果在步骤 ReadFromSpanner / Execute query / Read from Spanner / Read from Partitions 中发生超出截止期限错误,请查看查询统计信息表格,找出扫描了大量行的查询。然后,修改此类查询,以尝试缩短执行时间。

以下异常消息显示了另一个 Dataflow 超出截止期限错误示例:

exception:
     org.apache.beam.sdk.util.UserCodeException:
     com.google.cloud.spanner.SpannerException: DEADLINE_EXCEEDED:
     io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after
     3599.999905380s.
     [remote_addr=batch-spanner.googleapis.com/172.217.5.234:443] at
 org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)

导致此超时的原因是工作项过大。在上面的示例中,以下两个建议可能有所帮助。首先,您可以尝试启用 shuffle 服务(如果尚未启用)。其次,您可以尝试调整数据库读取中的配置,例如 maxPartitionspartitionSizeBytes。如需了解详情,请参阅 PartitionOptions 来尝试缩减工作项大小如需查看实现方法示例,请参阅此 Dataflow 模板

超出期限的额外问题排查资源

如果您在完成以下设置后仍看到 DEADLINE_EXCEEDED 错误, 问题排查步骤,请创建支持请求 会遇到以下情况:

  • Google Front End 延迟时间较长,但 Spanner API 请求延迟时间较短
  • Spanner API 请求延迟时间较长,但查询延迟时间较短

您还可以参阅以下问题排查资源: