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

本页介绍了在 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 数量的限制

数据吞吐量

与等效的 CRUD 方法相比,LRO 方法通常可实现更高的吞吐量。例如,使用 dicomStores.import 导入 DICOM 实例通常比使用 dicomStores.storeInstances 单独存储实例的效果更好。

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

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

如需在运行 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 导入操作之后,在 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 客户服务团队联系。如需提出申请,请参阅申请更多配额的最佳实践

如果您的输入数据量很大,例如:

  • 您要导入的 DICOM 实例大小为数百万兆字节 (PB)。
  • 您要导入数十亿个 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 导入了 1,000 万个 FHIR 资源,其中 50% 存在格式错误,那么由于速率限制和 Cloud Logging 配额,系统可能只会记录几百或几千个错误。

    记录的错误数量也会因 LRO 在出现高错误率时运行的时长而异。如果 LRO 运行缓慢,则可能会在 Cloud Logging 中显示更多错误,因为这些错误会在很长一段时间内分散出现,并且不受速率限制。

重试 LRO 的影响

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

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

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

重试 LRO

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

重试导入操作

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

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

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

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

  1. 您尝试导入 1,000,000 个 FHIR 资源。5 万个资源因格式错误而失败。
  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 配额问题。如需了解详情,请参阅管理配额以最大限度提高数据吞吐量配额管理最佳实践