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

このページでは、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 リソースのデータと形式が正しいこと
  • インポート中に発生したエラーは管理されます。

参照整合性を適用するには、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 が同じ場合は、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 でエラーが発生し、クライアント アプリケーションが同じデータを使用してオペレーションを自動的に再試行すると、再試行でより多くのエラーが発生する可能性があります。

インポートしようとした 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 の割り当てに関する問題。詳細については、データ スループットを最大化するために割り当てを管理する割り当て管理のベスト プラクティスをご覧ください。