長時間実行オペレーションのベスト プラクティス

このページでは、Cloud Healthcare API で長時間実行オペレーション(LRO)を実行して管理するためのベスト プラクティスについて説明します。Cloud Healthcare API の LRO の概要については、長時間実行オペレーションの管理をご覧ください。

LRO プロパティ

以降のセクションは、LRO を返すメソッドに記載されているメソッドに適用されます。

割り当ての影響

LRO は、次のタイプの割り当てを使用する Cloud Healthcare API の作成、読み取り、更新、削除(CRUD)メソッドと割り当てを共有しません。

LRO 割り当ては、fhir_store_lro_ops 指標と dicom_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 リソースのデータと形式が正しい
  • インポート中に発生したエラーは管理されます

参照整合性を適用するには、fhirStores.import ではなく fhir.create または fhir.executeBundle を使用します。詳細については、FHIR データのインポートとバンドルの実行をご覧ください。

Pub/Sub 通知

一部の Cloud Healthcare API メソッドは、医療リソースの作成や削除など、臨床イベントに関する Pub/Sub 通知を送信します。Pub/Sub 通知を送信するメソッドの一覧については、Pub/Sub 通知の構成をご覧ください。

次のインポート方法では、Pub/Sub 通知は送信されません。

インポートの完了時にアプリの一部で通知が必要な場合は、インポート内のデータを一覧表示できる別の通知方法を使用します。

エラー処理の上限

特に LRO が大量のデータを処理し、多数のエラーを生成する場合、Cloud Healthcare API は 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 カスタマーケアにお問い合わせください。リクエストを行うには、追加の割り当てをリクエストする際のベスト プラクティスをご覧ください。

入力データが大きい場合は、追加の割り当てが必要になることがあります。たとえば、次のような場合です。

  • 数ペタバイト(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.id フィールドと operation.producer フィールドを使用して、LRO のステータスとエラーを確認します。たとえば、projects.locations.datasets.fhirStores.import メソッドから呼び出された LRO には、operation.producer フィールドに import_fhir が含まれています。

    複数の LRO に同じ operation.idoperation.producer がある場合は、createTime タイムスタンプと endTime タイムスタンプを使用して、正しい 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 でエラーが発生し、クライアント アプリケーションが同じデータを使用してオペレーションを自動的に再試行すると、再試行によってさらにエラーが発生する可能性があります。

インポートしようとした FHIR リソースの一部が無効であるために、fhirStores.import LRO がエラーで終了するシナリオについて考えてみましょう。同じデータでインポートを自動的に再試行すると、一部の 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. 1,000,000 個の FHIR リソースをインポートしようとしています。50,000 個のリソースが、書式エラーが原因で失敗します。
  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 のスケジュールを決定します。多くの CRUD オペレーションが実行されているピーク時に実行されないように、LRO をスケジュールできます。詳細については、割り当てを管理してデータ スループットを最大化するをご覧ください。

モニタリングとアラートの受信

LRO をモニタリングし、アラートを解決する手順を作成、維持します。アラートは主に、LRO ステータスとキューイングの問題によって発生します。手順では、次の状況に対処する必要があります。

  • 構成された回数よりも多くの回数で再試行に失敗した LRO。
  • エラーのサブセットを解決するために人間による介入を必要とする問題。たとえば、LRO が失敗し、クライアントがエラーを解決できない場合は、人間による介入が必要になる可能性があります。人間による介入を必要とする問題を解決する方法について詳しくは、LRO のキューと管理をご覧ください。
  • キューの長さが超過している、または急速に増加している。
  • ポリシー要件が満たされていない(権限の問題や構成ミスなど)。
  • 複数の LRO にわたるシステム的な問題を示す整合性チェック。ソース データセットと宛先データセットに同じ数の FHIR リソースがあることを想定する複数の匿名化 LRO があるとします。時間の経過とともに増加する不一致がある場合は、未処理のデータを示している可能性があります。
  • LRO 割り当ての問題。詳細については、データ スループットを最大化するために割り当てを管理する割り当て管理のベスト プラクティスをご覧ください。