Solución de problemas de migración

En esta sección se ofrecen consejos para solucionar los problemas habituales que pueden surgir al crear y gestionar las canalizaciones de Datastream y Dataflow.

Solucionar problemas de un perfil de conexión de flujo de datos

Para llevar a cabo el procedimiento de migración, debe crear dos perfiles de conexión de Datastream: uno para leer datos de la base de datos de origen compatible con MongoDB y otro para escribir los datos en un segmento de Cloud Storage.

En estos pasos se usa el comando gcloud datastream connection-profiles create. Cuando creas un perfil de conexión de Datastream con este comando, se devuelven metadatos similares a los del siguiente ejemplo:

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

Puedes usar el identificador destacado que empieza por operation- para obtener el estado de la operación de Datastream. En el ejemplo de salida anterior, el siguiente comando de gcloud CLI obtiene detalles sobre la solicitud de creación del perfil de conexión:

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

Puede examinar los perfiles de conexión de Datastream y otros artefactos de Datastream en la Google Cloud consola.

En la Google Cloud consola, ve a la página Datastream:

Ir a Datastream

Solucionar problemas con un flujo de Datastream

Cuando crea un flujo de Datastream con el comando gcloud datastream streams create, devuelve metadatos similares a los del siguiente ejemplo:

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

Puedes usar el identificador destacado que empieza por operation- para obtener el estado de la operación de Datastream. En el ejemplo de salida anterior, el siguiente comando de gcloud CLI obtiene detalles sobre la solicitud de creación de la secuencia:

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

Para consultar el estado de una emisión, usa lo siguiente:

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

Puede examinar los flujos de Datastream y otros artefactos de Datastream en la Google Cloud consola.

En la Google Cloud consola, ve a la página Datastream:

Ir a Datastream

Solucionar problemas de la canalización de Dataflow

Puedes monitorizar la ejecución de la canalización de Dataflow en la consola de Google Cloud .

En la Google Cloud consola, ve a la página Dataflow:

Ir a Dataflow

Solucionar errores que se pueden volver a intentar

Los errores que se pueden volver a intentar son errores transitorios que se solucionarán con el tiempo. Los errores comunes que se pueden volver a intentar son los siguientes:

  • Problemas de red o de conectividad
  • Contención de transacciones
  • Conexiones cerradas debido al balanceo de carga

Los documentos que no se hayan podido escribir en el destino debido a errores se almacenarán en el segmento de Cloud Storage, en la ubicación especificada por el parámetro deadLetterQueueDirectory de la plantilla de Dataflow. Los errores que se pueden volver a intentar se volverán a intentar de forma predeterminada hasta el número de veces especificado por el parámetro dlqMaxRetryCount.

La cola de mensajes fallidos (DLQ) se puede inspeccionar directamente desde Cloud Storage. Para ello, ve a la ruta especificada en la DLQ_LOCATION variable de entorno. La ruta contendrá una jerarquía de carpetas con marcas de tiempo que incluirán registros JSON de documentos y actualizaciones que no se han podido escribir en la base de datos de Firestore con compatibilidad con MongoDB.

Si la cola de mensajes fallidos solo contiene documentos que no se han podido procesar debido a errores que se pueden volver a intentar, puedes intentar vaciar la cola ejecutando la plantilla de Dataflow en un modo que solo funcione en esta cola. Para ello, asigna el valor retryDLQ al parámetro runMode, como se muestra en el siguiente ejemplo:

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

Solucionar errores no reintentables

Estos son algunos de los errores no reintentables más habituales:

  • Tipos de BSON no admitidos
  • Tipos de BSON no admitidos usados como _id
  • No se admite 0L como _id
  • Tamaños de documentos superiores al límite de 4 MB de Firestore

Los errores no reintentables se almacenarán en el segmento de Cloud Storage, en la ubicación especificada por el parámetro deadLetterQueueDirectory de la plantilla de Dataflow.

Examinar la cola de mensajes fallidos (DLQ)

Una vez que se haya detenido todo el procesamiento, lo que significa que no se está procesando tráfico activo y no se están volviendo a intentar los eventos con errores, estos se conservan en Cloud Storage.

Para verificar que el procesamiento se ha detenido, inspecciona los eventos de escritura transaccional y confirma que no hay un volumen de procesamiento y que no se están generando nuevas entradas de registro.

Puedes inspeccionar la DLQ directamente desde Cloud Storage:

  1. Ve a la ubicación de Cloud Storage especificada en la variable de entorno DLQ_LOCATION.
  2. En el árbol de carpetas anidadas creado según las marcas de tiempo, expande las carpetas para ver el contenido más reciente de la cola. Los archivos podrían haberse fragmentado y tener un aspecto similar al del siguiente ejemplo:

    Archivos en la cola de mensajes fallidos

  3. Inspecciona cada archivo para ver los documentos y las actualizaciones que no se han aplicado a la base de datos de destino. Cada mensaje contendrá una carga útil del evento original y la excepción que se haya producido.

    Es muy poco probable que se produzcan errores que se puedan volver a intentar, sobre todo si se ha usado un valor bajo para el parámetro dlqMaxRetryCount, pero, por lo general, los eventos que acaban en la cola de mensajes fallidos no se podrán volver a intentar por los motivos descritos anteriormente.

  4. Puede abortar la migración y reanudar el tráfico de la aplicación a la base de datos de origen, solucionar las restricciones de datos de Firestore en la base de datos de origen y volver a ejecutar todo el proceso de migración. También puede solucionar los problemas de datos con cada evento de cola de mensajes fallidos y volver a intentar procesar estos eventos.

En cada fila de cada archivo de cola de mensajes fallidos, puede hacer lo siguiente:

  • Convierte los tipos de datos no admitidos en un tipo de datos alternativo editando la carga útil del documento. La carga útil del documento estará en formato JSON extendido canónico. Expresa el nuevo tipo de datos en formato JSON extendido canónico.

  • Reasigna el documento 0L _id a un nuevo Long o a otro tipo de datos, como String. Si se asigna a otro tipo de datos, es posible que sea necesario cambiar la lógica de la aplicación si el código actual espera que todos los _id sean Longs.

  • Los documentos que superen el límite de 4 MB de Firestore se pueden separar en documentos más pequeños o se puede comprimir su contenido. Sin embargo, esto requeriría cambios en la lógica de la aplicación para gestionar los datos.

  • Ignora el evento eliminando la fila del archivo de cola de mensajes fallidos.

Para modificar los archivos de la cola de mensajes fallidos, deberá descargar los archivos .json localmente, modificar el contenido y volver a subirlos a la misma ubicación de Cloud Storage, sobrescribiendo el archivo original. Si todos los documentos a los que se hace referencia en el archivo se pueden excluir de la migración de forma segura, se puede eliminar todo el archivo.

Una vez que hayas modificado los archivos de la cola de mensajes fallidos, puedes volver a ejecutar estos eventos mediante la plantilla de Dataflow de migración en el modo retryDLQ.

El siguiente comando inicia una nueva canalización de Dataflow que solo procesará los elementos de la cola de mensajes fallidos:

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

Siguientes pasos