长时间运行的操作最佳实践

本页面介绍了在 Cloud Healthcare API 中运行和管理长时间运行的操作 (LRO) 的最佳实践。如需大致了解 Cloud Healthcare API 中的 LRO,请参阅管理长时间运行的操作

LRO 属性

下面几部分适用于返回 LRO 的方法中列出的方法。

配额影响

LRO 不会与使用以下类型的配额的 Cloud Healthcare API 创建、读取、更新和删除 (CRUD) 方法共享配额:

LRO 配额使用 fhir_store_lro_opsdicom_store_lro_ops 指标计算得出。

Cloud Healthcare API 会限制可在 Google Cloud 项目中并发运行的 LRO 数量。如需了解详情,请参阅 LRO 数量限制

数据吞吐量

LRO 方法通常会比等效的 CRUD 方法实现更高的数据吞吐量。例如,导入 dicomStores.import 的 DICOM 实例通常优于使用 dicomStores.storeInstances 逐个存储实例。

由于以下限制,同时运行多个 LRO 可能不会提高数据吞吐量,尤其是在处理大量数据时:

  • 配额限制
  • 资源争用
  • 运行 LRO 时,您的 Google Cloud 项目发送到 Cloud Healthcare API 的其他流量

在运行 LRO 时,如需最大限度地提高数据吞吐量,请考虑以下事项:

  • 由于开销,小批量导入和导出批次的吞吐量通常较低。
  • LRO 与其他 Cloud Healthcare API 操作分开运行并消耗配额。
  • 每个 LRO 都有最大吞吐量。
  • 同一资源的并发 LRO 可能会导致锁争用。
  • Cloud Healthcare API 会限制可在 Google Cloud 项目中并发运行的 LRO 数量。如需了解详情,请参阅 LRO 数量限制

针对用例所需的 LRO 的数量进行规划。如果必须跨多个 LRO 对大型数据批次进行分区,请尝试尽量减少分区数量。

FHIR 参照完整性

fhirStores.import 方法不会考虑 disableReferentialIntegrity 设置。这样一来,您就可以使用不需要顺序或分组的任意相互依赖关系来导入数据,从而提高数据吞吐量。如果输入数据包含无效引用,或者某些 FHIR 资源导入失败,FHIR 存储区的状态可能会违反参照完整性

如需使用 fhirStores.import,您的客户端应用需要验证以下内容,以确保 FHIR 资源引用有效:

  • FHIR 资源数据和格式正确无误
  • 导入期间发生的任何错误都可以进行管理

如需强制执行参照完整性,请使用 fhir.createfhir.executeBundle(而非 fhirStores.import)。如需了解详情,请参阅导入 FHIR 数据与执行捆绑包

Pub/Sub 通知

某些 Cloud Healthcare API 方法会针对临床事件(例如创建或删除医疗保健资源)发送 Pub/Sub 通知。如需查看发送 Pub/Sub 通知的方法列表,请参阅配置 Pub/Sub 通知

以下导入方法不发送 Pub/Sub 通知:

如果应用的某些部分需要在导入完成后收到通知,请使用其他通知方法列出导入中的数据。

错误处理限制

Cloud Healthcare API 可能不会记录 LRO 中的所有错误,尤其是在 LRO 处理大量数据并产生许多错误的情况下。实现一种方法来分别跟踪 LRO 处理和错误。如需了解详情,请参阅资源错误处理

数据和搜索索引

由于异步搜索索引,可能会导致搜索结果延迟。如果 LRO 创建或更新 FHIR 资源,相应更改可能需要更长时间才能显示在搜索结果中。

例如,在 FHIR 导入操作完成后,搜索患者资源时可能不会立即返回所有结果。

执行顺序

LRO 是根据 Google Cloud 资源可用性安排的。LRO 的执行顺序和完成顺序可能与请求的顺序不匹配。

避免小规模的导入和导出请求

本部分介绍处理小数据量时的 LRO 限制。

通过导入和导出操作返回的 LRO 可通过快速处理大量数据并避免负载峰值来增加数据吞吐量。如需存储少量数据,请使用存储数据的最佳做法中的另一种方法。

LRO 数量限制

Cloud Healthcare API 会限制可在 Google Cloud 项目中并发运行的 LRO 数量。该限制基于以下因素:

  • LRO 的类型。
  • 分配给 LRO 的 Google Cloud 资源量。该指标取决于输入数据的大小。

如果您运行太多 LRO,则 Cloud Healthcare API 速率限制、生成错误,并且可能会降低 LRO 吞吐量。Cloud Healthcare API 会自动节省 Google Cloud 资源,使 LRO 数量保持在资源限制范围内。

LRO 是后台进程,因此,如果来自 LRO 的负载干扰优先级较高的进程(例如 CRUD 操作),Cloud Healthcare API 可能会降低 LRO 吞吐量。这样可确保优先级较高的进程可用。

资源分配和清理开销

LRO 启动时,Cloud Healthcare API 会分配资源。这可能需要几分钟的时间,因为 Cloud Healthcare API 必须执行以下操作:

  1. 启动控制器进程。
  2. 从工作器池中分配工作器。
  3. 确定输入数据的大小。
  4. 开始大规模分配工作。

停止和清理 LRO 可能需要几分钟时间。

由于存在开销,处理少量数据的 LRO 可能会花费大部分时间来分配工作器池和清理资源。

如果您有许多此类 LRO,则可能会遇到数据吞吐量较低,因为更有可能达到 Google Cloud 项目配额限制。

有关请求 LRO 配额的限制

在申请更多 LRO 配额之前,请实施配额管理最佳实践。如果您仍需要更多配额,请与 Google Cloud Customer Care 团队联系。如需发出请求,请参阅申请更多配额的最佳做法

如果输入数据较大,您可能需要额外的配额,例如:

  • 您将导入大小为多个 PB (PB) 的 DICOM 实例。
  • 您正在导入数百亿 FHIR 资源。

LRO 状态和失败状态

启动 LRO 时,响应包含唯一 ID。您可以通过轮询 LRO 的 ID 来查看其状态。LRO 完成后,它将处于以下状态之一:

  • 已成功完成,未出现错误
  • 已成功完成,但存在一些错误
  • 未能完成,但可能在失败前生成了部分输出

以下 JSON 示例描述了 LRO 完成后返回的响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "METADATA_TYPE",
    "apiMethodName": "API_METHOD_NAME",
    "createTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
    "endTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
    "logsUrl": "https://console.cloud.google.com/CLOUD_LOGGING_URL"
    "counter": {
      "success": "SUCCESS_COUNT",
      // If there were any failures, they display in the `failure` field.
      "failure": "FAILURE_COUNT"
    }
  },
  "done": true,
  // The `response` field only displays if there were no errors.
  "response": {
    "@type":
  },
  // If there were any errors, an `error` field displays instead of a `response` field.
  // See Troubleshooting long-running operations for a list of response codes.
  "error": {
    "code": ERROR_CODE,
    "message": "DESCRIPTION",
    "details": [
      {
        "@type": "...",
        FIELD1: ...,
        ...
      }
    ]
  }
}

如需获取 LRO 的状态、列出 LRO 和取消 LRO,请参阅管理长时间运行的操作

管理 LRO 状态和失败状态

如需管理 LRO 状态和失败状态,请遵循以下最佳实践:

  • 轮询 LRO,以获取其状态并验证何时完成。如需轮询 LRO,请重复调用 projects.locations.datasets.operations.get 方法,直到操作完成。请在每个轮询请求之间退避,例如 10 秒。当响应包含 "done": true 时,LRO 已完成。
  • LRO 完成后,检查响应是否包含 error 字段。如果确实如此,请根据以下因素判断是否重试该操作:

    • 错误代码。如需了解错误代码和建议的操作,请参阅对 LRO 进行问题排查
    • 已发生的重试次数。
    • LRO 开始到发生错误之间的时间。例如,如果某个 LRO 通常需要几个小时才能完成,但未返回失败状态,您可能需要人工干预。如需详细了解何时可能需要人工干预,请参阅针对最终的错误状态制定计划

    如需了解如何重试 LRO,请参阅将 LRO 加入队列

  • 如果不重试 LRO,请查看 metadata.counter.failure 字段以了解特定资源上是否发生了错误。您或许可以逐个处理各项资源。 如需了解详情,请参阅处理资源错误

处理资源错误

LRO 可能会在出现错误后结束。LRO 响应中的错误遵循 Google Cloud 错误模型。LRO 响应包含指向 Cloud Logging 的链接,用于了解详情。

LRO 错误详情

Cloud Logging 中的 LRO 错误具有以下属性:

  • Cloud Logging 错误日志不包含 LRO ID。使用 operation.idoperation.producer 字段查找 LRO 的状态和错误。例如,从 projects.locations.datasets.fhirStores.import 方法调用的 LRO 在 operation.producer 字段中包含 import_fhir

    如果多个 LRO 具有相同的 operation.idoperation.producer,请使用 createTimeendTime 时间戳来标识正确的 LRO。

  • 并非所有 LRO 错误都存在于 Cloud Logging 中。由于以下原因,metadata.counter.failure 字段可能会超出记录的实际错误数量:

    • Cloud Logging 配额限制
    • Cloud Logging 服务可用性
    • LRO 日志限制

    例如,如果 LRO 导入了 1000 万个 FHIR 资源,并且其中 50% 存在格式错误,则由于速率限制和 Cloud Logging 配额,系统可能只会记录几百或几千个错误。

    记录的错误数量还会因 LRO 的运行时长以及遇到较高的错误率而有所不同。如果 LRO 运行缓慢,则可能会在 Cloud Logging 中显示更多错误,因为这些错误分布在很长一段时间内,并且不受速率限制。

重试 LRO 的影响

如果 LRO 遇到错误,并且客户端应用使用相同的数据自动重试操作,重试可能会导致更多错误。

假设 fhirStores.import LRO 完成时会出现错误,因为它尝试导入的一些 FHIR 资源无效。由于部分 FHIR 资源已在原始操作中导入,因此使用相同数据自动重试导入可能会导致许多 409 ALREADY_EXISTS 错误。如果您在查询 LRO 后发现创建操作失败,请勿自动重试。人工检查应有 409 ALREADY_EXISTS 个错误。

如果重试成功,metadata.counter.failure 字段不会包含之前操作的错误。这可能会导致错误数不正确,因为成功重试的响应不包含之前尝试的错误。

重试 LRO

如果您有客户端处理流水线来检测 LRO 错误,请勿使用 Cloud Logging。如 LRO 错误详情中所示,LRO 的 Cloud Logging 错误日志不可靠且不完整。请使用以下部分中的方法。

重新尝试导入操作

如需检测未能导入的数据,请将 Cloud Healthcare API 中导入的数据与 Cloud Storage 中的源数据进行比较。您可以使用以下方法导入数据:

使用唯一标识符(例如 FHIR 患者资源的医疗记录编号 (MRN))来比较数据。

如需了解重试导入操作时要执行的步骤,请参阅重试 LRO 的影响

重新运行导入作业可能会重新创建之前删除的资源。考虑以下场景:

  1. 您尝试导入 100 万个 FHIR 资源。50000 个资源因格式错误而失败。
  2. 您需要花几天时间修正格式错误。在此期间,患者请求您移除他们的记录。
  3. 如果您重新运行导入作业,可能会重新创建已删除的患者数据。

重试导出操作

如需检测未能导出到 BigQuery 的数据,请编写一个脚本,将源数据中的唯一 ID 与导出的数据进行比较。

您可以使用以下方法将数据导出到 BigQuery:

将 LRO 加入队列并管理队列

如果您运行处理初始配置或定期安排的大量数据 LRO,请实施以下 LRO 排队方法:

  • 将并发 LRO 限制为较小的数字,例如 5。您可以根据运行的 LRO 的大小和类型调整此限制。
  • 监控 LRO 完成情况。如果出现错误,请重新安排 LRO 或在处理流水线中单独解决错误。
  • 尽可能自动解决处理资源错误中的错误。

    • 了解 FHIR 导入的用例以确定是忽略 409 ALREADY_EXISTS 错误,还是单独执行 CRUD 操作来解决这些错误。如 LRO 错误详情中所示,某些 409 ALREADY_EXISTS 错误可能不会记录到 Cloud Logging。如果您的应用依赖于错误日志,请使用重试 LRO 中的其中一种方法。

    • 如需解决一些错误,请为遇到这些错误的数据加入较小的 LRO 或执行单独的 CRUD 操作。

    • 如需解决很多错误,为确保一致性,重新运行 LRO 可能是最简单的方法。如需了解对已删除数据重新运行导入操作的风险,请参阅重试导入操作

  • 自动检测是否需要人工干预才能解决错误。 您应该为系统管理员提供工具和操作策略方案。解决错误的任务可能包括:

    • 重新安排 LRO。
    • 重新安排以前的 LRO 数据的子集。
    • 请查看错误并处理遇到错误的各个数据元素。只有在您可以确定已记录 LRO 中的所有错误时,才能执行此任务。
  • 确定 LRO 时间表。您可以安排 LRO 以避免在许多 CRUD 操作运行时在高峰时段运行。如需了解详情,请参阅管理配额以最大限度地提高数据吞吐量

监控和接收提醒

创建和维护用于监控 LRO 和解决提醒的流程。提醒主要由 LRO 状态和队列问题导致。手术应解决以下情况:

  • LRO 的重试失败次数超过其配置的次数。
  • 需要人工干预才能解决部分错误的问题。 例如,如果 LRO 失败,并且客户端无法解决错误,则可能需要人工干预。如需详细了解如何解决需要人为干预的问题,请参阅对 LRO 进行队列和管理
  • 超出长度或增长速度太快的队列。
  • 不符合政策要求,例如权限问题或配置错误。
  • 显示多个 LRO 的系统性问题的一致性检查。您可能有多个去标识化的 LRO,这些 LRO 预计源数据集和目标数据集具有相同数量的 FHIR 资源。如果出现差异随时间推移而不断增加,则可能表示数据尚未处理。
  • LRO 配额问题。如需了解详情,请参阅管理配额以最大限度地提高数据吞吐量配额管理最佳实践