Résoudre les problèmes de migration

Cette section fournit des conseils pour résoudre les problèmes courants qui peuvent survenir lors de la création et de la gestion de pipelines Datastream et Dataflow.

Résoudre les problèmes liés à un profil de connexion Datastream

La procédure de migration vous oblige à créer deux profils de connexion Datastream : l'un pour lire les données de la base de données source compatible avec MongoDB et l'autre pour écrire les données dans un bucket Cloud Storage.

Ces étapes utilisent la commande gcloud datastream connection-profiles create. Lorsque vous créez un profil de connexion Datastream avec cette commande, il renvoie des métadonnées semblables à l'exemple suivant :

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

Vous pouvez utiliser l'identifiant en surbrillance commençant par operation- pour récupérer l'état de l'opération Datastream donnée. Pour l'exemple de résultat ci-dessus, la commande gcloud CLI suivante récupère les détails de la demande de création du profil de connexion :

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

Vous pouvez examiner les profils de connexion Datastream et d'autres artefacts Datastream dans la console Google Cloud .

Dans la console Google Cloud , accédez à la page Datastream :

Accéder à Datastream

Résoudre les problèmes liés à un flux Datastream

Lorsque vous créez un flux Datastream avec la commande gcloud datastream streams create, il renvoie des métadonnées semblables à l'exemple suivant :

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

Vous pouvez utiliser l'identifiant en surbrillance commençant par operation- pour récupérer l'état de l'opération Datastream donnée. Pour l'exemple de résultat ci-dessus, la commande gcloud CLI suivante récupère les détails de la demande de création de flux :

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

Pour rechercher l'état d'un flux existant, utilisez la commande suivante :

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

Vous pouvez examiner les flux Datastream et d'autres artefacts Datastream dans la console Google Cloud .

Dans la console Google Cloud , accédez à la page Datastream :

Accéder à Datastream

Résoudre les problèmes liés au pipeline Dataflow

Vous pouvez surveiller l'exécution du pipeline Dataflow dans la console Google Cloud .

Dans la console Google Cloud , accédez à la page Dataflow :

Accéder à Dataflow

Résoudre les erreurs récupérables

Les erreurs récupérables sont des erreurs temporaires qui finiront par être résolues. Voici quelques erreurs courantes pouvant être réessayées :

  • Problèmes de réseau ou de connectivité
  • Contention des transactions
  • Connexions fermées en raison de l'équilibrage de charge

Les documents qui n'ont pas pu être écrits dans la destination en raison d'erreurs seront stockés dans le bucket Cloud Storage, à l'emplacement spécifié par le paramètre deadLetterQueueDirectory du modèle Dataflow. Par défaut, les erreurs pouvant faire l'objet d'une nouvelle tentative seront réessayées jusqu'au nombre de fois spécifié par le paramètre dlqMaxRetryCount.

La file d'attente des messages non distribués (DLQ) peut être inspectée directement depuis Cloud Storage en accédant au chemin d'accès spécifié dans la variable d'environnement DLQ_LOCATION. Le chemin d'accès contiendra une hiérarchie de dossiers horodatés, contenant des enregistrements JSON de documents et de mises à jour qui n'ont pas pu être écrits dans la base de données Firestore avec compatibilité MongoDB.

En supposant que la file d'attente des messages non distribués ne contienne que des documents ayant échoué en raison d'erreurs pouvant être corrigées, vous pouvez essayer de vider la file d'attente en exécutant le modèle Dataflow dans un mode qui ne fonctionne que sur cette file d'attente. Pour ce faire, définissez le paramètre runMode sur retryDLQ, comme indiqué dans l'exemple suivant :

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

Résoudre les erreurs non réessayables

Voici quelques erreurs non réessayables courantes :

  • Types BSON non compatibles
  • Types BSON non acceptés utilisés comme _id
  • 0L non compatible en tant que _id
  • Tailles de documents supérieures à la limite de 4 Mo de Firestore

Les erreurs non réessayables sont stockées dans le bucket Cloud Storage, à l'emplacement spécifié par le paramètre deadLetterQueueDirectory du modèle Dataflow.

Examiner la file d'attente de lettres mortes

Une fois tout traitement arrêté, ce qui signifie qu'aucun trafic actif n'est en cours de traitement et qu'aucun événement ayant généré une erreur n'est en cours de nouvelle tentative, les événements ayant généré une erreur sont conservés dans Cloud Storage.

Pour vérifier que le traitement s'est arrêté, inspectez les événements d'écriture transactionnelle et assurez-vous qu'il n'y a aucun débit de traitement et qu'aucune nouvelle entrée de journal n'est générée.

Vous pouvez inspecter la DLQ directement depuis Cloud Storage :

  1. Accédez à l'emplacement Cloud Storage spécifié dans la variable d'environnement DLQ_LOCATION.
  2. Dans l'arborescence des dossiers imbriqués construits en fonction des codes temporels, développez les dossiers pour afficher le dernier contenu de la file d'attente. Les fichiers peuvent avoir été fragmentés et ressembler à l'exemple suivant :

    Fichiers dans la DLQ

  3. Inspectez chaque fichier pour afficher les documents et les mises à jour qui n'ont pas été appliqués à la base de données de destination. Chaque message contiendra une charge utile de l'événement d'origine et de l'exception qui s'est produite.

    Il est très peu probable que des erreurs pouvant être relancées soient présentes, en particulier si une faible valeur a été utilisée pour le paramètre dlqMaxRetryCount. Toutefois, en général, les événements qui se retrouvent dans la DLQ ne peuvent pas être relancés pour les raisons décrites précédemment.

  4. Vous pouvez choisir d'abandonner la migration et de rétablir le trafic d'application vers la base de données source, en résolvant les contraintes de données Firestore dans la base de données source et en relançant l'ensemble du processus de migration. Vous pouvez également résoudre les problèmes de données avec chaque événement DLQ et réessayer de traiter ces événements.

Pour chaque ligne de chaque fichier DLQ, vous pouvez :

  • Convertissez les types de données non compatibles en un autre type de données en modifiant la charge utile du document. La charge utile du document sera au format JSON étendu canonique. Exprimez le nouveau type de données au format JSON étendu canonique.

  • Réattribuez le document 0L _id à un nouveau Long ou à un autre type de données tel que String. Si vous réattribuez un autre type de données, vous devrez peut-être modifier la logique de l'application si le code existant s'attend à ce que les _id soient tous des longs.

  • Les documents qui dépassent la limite de 4 Mo de Firestore peuvent être divisés en documents plus petits ou leur contenu peut être compressé. Toutefois, cela nécessiterait de modifier la logique de l'application pour gérer les données.

  • Ignorez l'événement en supprimant la ligne du fichier DLQ.

Pour modifier les fichiers de la DLQ, vous devez télécharger le ou les fichiers .json en local, modifier leur contenu, puis les réimporter au même emplacement Cloud Storage, en écrasant le fichier d'origine. Si tous les documents référencés dans le fichier peuvent être exclus de la migration sans risque, l'intégralité du fichier peut être supprimée.

Une fois que vous avez modifié les fichiers DLQ, vous pouvez réexécuter ces événements à l'aide du modèle Dataflow de migration en mode retryDLQ.

La commande suivante démarre un pipeline Dataflow qui ne traitera que les éléments de la file d'attente des messages non distribués :

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

Étapes suivantes