移行のトラブルシューティング

このセクションでは、Datastream と Dataflow のパイプラインの作成と管理で発生する可能性のある一般的な問題のトラブルシューティングのヒントを紹介します。

Datastream 接続プロファイルのトラブルシューティング

移行手順では、2 つの Datastream 接続プロファイルを作成する必要があります。1 つは移行元 MongoDB 互換データベースからデータを読み取るためのプロファイル、もう 1 つは Cloud Storage バケットにデータを書き込むためのプロファイルです。

これらの手順では、gcloud datastream connection-profiles create コマンドを使用します。このコマンドを使用して Datastream 接続プロファイルを作成すると、次の例のようなメタデータが返されます。

metadata:
  '@type': type.googleapis.com/google.cloud.datastream.v1.OperationMetadata
  apiVersion: v1
  createTime: '2025-05-15T21:49:05.022509533Z'
  requestedCancellation: false
  target: projects/PROJECT_ID/locations/LOCATION/connectionProfiles/SRC_CONNECTION_PROFILE_NAME
  verb: create
name: projects/PROJECT_ID/locations/LOCATION/operations/operation-1747345744961-63533a26d9ee6-b2386fbf-204c28d6

operation- で始まるハイライト表示された識別子を使用して、指定された Datastream オペレーションのステータスを取得できます。上記の出力例では、次の gcloud CLI コマンドで接続プロファイル作成リクエストの詳細を取得します。

gcloud datastream operations describe \
operation-1747345744961-63533a26d9ee6-b2386fbf-204c28d6 \
--location="$LOCATION"

Google Cloud コンソールで、Datastream 接続プロファイルやその他の Datastream アーティファクトを確認できます。

Google Cloud コンソールで、[Datastream] ページに移動します。

Datastream に移動

Datastream ストリームのトラブルシューティング

gcloud datastream streams create コマンドで Datastream ストリームを作成すると、次の例のようなメタデータが返されます。

metadata:
  '@type': type.googleapis.com/google.cloud.datastream.v1.OperationMetadata
  apiVersion: v1
  createTime: '2025-05-14T19:31:20.209503095Z'
  requestedCancellation: false
  target: projects/PROJECT_ID/locations/LOCATION/streams/DATASTREAM_NAME
  verb: create
  name: projects/PROJECT_ID/locations/LOCATION/operations/operation-1747251080085-6351d97f63eb8-43204f78-35c87474

operation- で始まるハイライト表示された識別子を使用して、指定された Datastream オペレーションのステータスを取得できます。上記の出力例では、次の gcloud CLI コマンドでストリーム作成リクエストの詳細を取得します。

gcloud datastream operations describe \
operation-1747345744961-63533a26d9ee6-b2386fbf-204c28d6 \
--location="$LOCATION"

既存のストリームのステータスを調べるには、次のコマンドを使用します。

gcloud datastream streams describe $DATASTREAM_NAME --location=$LOCATION

Google Cloud コンソールで、Datastream ストリームやその他の Datastream アーティファクトを確認できます。

Google Cloud コンソールで、[Datastream] ページに移動します。

Datastream に移動

Dataflow パイプラインのトラブルシューティング

Dataflow パイプラインの実行は Google Cloud コンソールでモニタリングできます。

Google Cloud コンソールで、[Dataflow] ページに移動します。

Dataflow に移動

再試行可能なエラーのトラブルシューティング

再試行可能なエラーは、最終的に成功する一時的なエラーです。一般的な再試行可能なエラーは次のとおりです。

  • ネットワークまたは接続に関する問題
  • トランザクションの競合
  • ロード バランシングによる接続の終了

エラーのため宛先に書き込めなかったドキュメントは、Cloud Storage バケットに保存されます。保存場所は、Dataflow テンプレートの deadLetterQueueDirectory パラメータで指定します。再試行可能なエラーは、デフォルトで dlqMaxRetryCount パラメータで指定された回数まで再試行されます。

デッドレター キュー(DLQ)は、DLQ_LOCATION 環境変数で指定されたパスに移動することで、Cloud Storage から直接検査できます。パスには、タイムスタンプ付きのフォルダの階層が含まれます。このフォルダには、MongoDB 互換の Firestore データベースに書き込めなかったドキュメントと更新の JSON レコードが含まれます。

再試行可能なエラーが原因で失敗したドキュメントのみがデッドレター キューに含まれていると仮定すると、このキューでのみ動作するモードで Dataflow テンプレートを実行して、キューのドレインを試みることができます。これを行うには、次の例に示すように、runMode パラメータを retryDLQ に設定します。

DLQ_START_TIME="$(date +'%Y%m%d%H%M%S')"

gcloud dataflow flex-template run "dataflow-mongodb-to-firestore-$DLQ_START_TIME" \
--template-file-gcs-location gs://dataflow-templates-us-central1/latest/flex/Cloud_Datastream_MongoDB_to_Firestore \
--region $LOCATION \
--num-workers $NUM_WORKERS \
--temp-location $TEMP_OUTPUT_LOCATION \
--additional-user-labels "" \
--parameters inputFilePattern=$INPUT_FILE_LOCATION,\
inputFileFormat=avro,\
fileReadConcurrency=10,\
connectionUri=$FIRESTORE_CONNECTION_URI,\
databaseName=$FIRESTORE_DATABASE_NAME,\
shadowCollectionPrefix=shadow_,\
batchSize=500,\
deadLetterQueueDirectory=$DLQ_LOCATION,\
dlqRetryMinutes=10,\
dlqMaxRetryCount=500,\
processBackfillFirst=false,\
runMode=retryDLQ,\
directoryWatchDurationInMinutes=10,\
streamName=$DATASTREAM_NAME,\
stagingLocation=$STAGING_LOCATION,\
autoscalingAlgorithm=THROUGHPUT_BASED,\
maxNumWorkers=$MAX_WORKERS,\
workerMachineType=$WORKER_TYPE

再試行できないエラーのトラブルシューティング

再試行できない一般的なエラーは次のとおりです。

  • サポートされていない BSON 型
  • _id として使用されているサポートされていない BSON 型
  • _id としての 0L はサポートされていません
  • Firestore の 4 MB の上限を超えるドキュメント サイズ

再試行できないエラーは、Dataflow テンプレートの deadLetterQueueDirectory パラメータで指定されたロケーションにある Cloud Storage バケットに保存されます。

デッドレター キュー(DLQ)の調査

すべての処理が停止した後(アクティブなトラフィックが処理されず、エラー イベントが再試行されない状態)、エラー イベントは Cloud Storage に永続化されます。

処理が停止したことを確認するには、トランザクション書き込みイベントを検査し、処理スループットがないことと、新しいログエントリが生成されていないことを確認します。

Cloud Storage から DLQ を直接検査できます。

  1. DLQ_LOCATION 環境変数で指定された Cloud Storage の場所に移動します。
  2. タイムスタンプに従って構築されたネストされたフォルダのツリーで、フォルダを開いてキュー内の最新のコンテンツを表示します。ファイルはシャーディングされている可能性があり、次の例のようになります。

    DLQ 内のファイル

  3. 各ファイルを検査して、宛先データベースに適用されなかったドキュメントと更新を表示します。各メッセージには、元のイベントのペイロードと発生した例外が含まれます。

    特に dlqMaxRetryCount パラメータに小さい値が使用された場合は、再試行可能なエラーが存在する可能性は非常に低いですが、通常、DLQ に送られるイベントは、前述の理由により再試行できません。

  4. 移行を中止して、アプリケーション トラフィックをソース データベースに再開し、ソース データベースの Firestore データ制約に対処して、移行プロセス全体を再実行するか、各 DLQ イベントでデータの問題に対処して、これらのイベントの処理を再試行するかを選択します。

各 DLQ ファイルの各行に対して、次の操作を行うことができます。

  • ドキュメント ペイロードを編集して、サポートされていないデータ型を代替データ型に変換します。ドキュメント ペイロードは、正規の拡張 JSON 形式になります。新しいデータ型を正規の拡張 JSON 形式で表現します。

  • 0L ドキュメント _id を新しい Long または String などの別のデータ型に再割り当てします。既存のコードで _id がすべて Long であることが想定されている場合、別のデータ型に再割り当てするには、アプリケーション ロジックの変更が必要になることがあります。

  • Firestore の 4 MB の上限を超えるドキュメントは、小さなドキュメントに分割するか、内容を圧縮できます。ただし、この場合はデータを処理するためにアプリケーション ロジックを変更する必要があります。

  • DLQ ファイルから行を削除して、イベントを無視します。

DLQ ファイルを変更するには、.json ファイルをローカルにダウンロードし、内容を変更して、同じ Cloud Storage の場所に再アップロードし、元のファイルを上書きする必要があります。ファイルで参照されているすべてのドキュメントを移行から安全に除外できる場合は、ファイル全体を削除できます。

DLQ ファイルを変更したら、retryDLQ モードで移行 Dataflow テンプレートを使用してこれらのイベントを再実行できます。

次のコマンドは、デッドレター キュー内のアイテムのみを処理する新しい Dataflow パイプラインを開始します。

DLQ_START_TIME="$(date +'%Y%m%d%H%M%S')"

gcloud dataflow flex-template run "dataflow-mongodb-to-firestore-$DLQ_START_TIME" \
--template-file-gcs-location gs://dataflow-templates-us-central1/latest/flex/Cloud_Datastream_MongoDB_to_Firestore \
--region $LOCATION \
--num-workers $NUM_WORKERS \
--temp-location $TEMP_OUTPUT_LOCATION \
--additional-user-labels "" \
--parameters inputFilePattern=$INPUT_FILE_LOCATION,\
inputFileFormat=avro,\
fileReadConcurrency=10,\
connectionUri=$FIRESTORE_CONNECTION_URI,\
databaseName=$FIRESTORE_DATABASE_NAME,\
shadowCollectionPrefix=shadow_,\
batchSize=500,\
deadLetterQueueDirectory=$DLQ_LOCATION,\
dlqRetryMinutes=10,\
dlqMaxRetryCount=500,\
processBackfillFirst=false,\
runMode=retryDLQ,\
directoryWatchDurationInMinutes=10,\
streamName=$DATASTREAM_NAME,\
stagingLocation=$STAGING_LOCATION,\
autoscalingAlgorithm=THROUGHPUT_BASED,\
maxNumWorkers=$MAX_WORKERS,\
workerMachineType=$WORKER_TYPE

次のステップ