Solución de problemas de migración

En esta sección, se proporcionan sugerencias para solucionar problemas comunes que pueden surgir cuando se crean y administran canalizaciones de Datastream y Dataflow.

Soluciona problemas de un perfil de conexión de Datastream

El procedimiento de migración requiere que crees 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 bucket 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 al 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 comienza con operation- para recuperar el estado de la operación de Datastream determinada. En el ejemplo de salida anterior, el siguiente comando de gcloud CLI recupera detalles sobre la solicitud de creación del perfil de conexión:

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

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

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

Ir a Datastream

Soluciona problemas en un flujo de Datastream

Cuando creas un flujo de Datastream con el comando gcloud datastream streams create, se devuelven metadatos similares al 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 comienza con operation- para recuperar el estado de la operación de Datastream determinada. En el ejemplo de salida anterior, el siguiente comando de gcloud CLI recupera detalles sobre la solicitud de creación de transmisión:

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

Para buscar el estado de una transmisión existente, usa el siguiente comando:

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

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

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

Ir a Datastream

Soluciona problemas de la canalización de Dataflow

Puedes supervisar la ejecución de la canalización de Dataflow en Google Cloud console.

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

Ir a Dataflow

Soluciona problemas relacionados con errores que se pueden volver a intentar

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

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

Los documentos que no se pudieron escribir en el destino debido a errores se almacenarán en el bucket de Cloud Storage, en la ubicación especificada por el parámetro deadLetterQueueDirectory de la plantilla de Dataflow. De forma predeterminada, los errores que se admiten para reintentar el envío se reintentarán hasta la cantidad de veces especificada por el parámetro dlqMaxRetryCount.

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

Si supones que la cola de mensajes no entregados solo contiene documentos que fallaron debido a errores reintentables, puedes intentar vaciar la cola ejecutando la plantilla de Dataflow en un modo que solo opere en esta cola. Para ello, configura el parámetro runMode como retryDLQ, 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

Solución de problemas relacionados con errores que no se pueden reintentar

Los errores comunes que no se pueden volver a intentar son los siguientes:

  • Tipos de BSON no admitidos
  • Tipos de BSON no admitidos que se usan 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 bucket de Cloud Storage, en la ubicación especificada por el parámetro deadLetterQueueDirectory de la plantilla de Dataflow.

Cómo examinar la cola de mensajes no entregados (DLQ)

Una vez que se detiene todo el procesamiento, lo que significa que no se está procesando tráfico activo ni se están reintentando eventos con errores, los eventos con errores se conservan en Cloud Storage.

Para verificar que el procesamiento se detuvo, inspecciona los eventos de escritura transaccional y confirma que no haya capacidad de procesamiento y que no se generen nuevas entradas de registro.

Puedes inspeccionar la DLQ directamente desde Cloud Storage:

  1. Navega a la ubicación de Cloud Storage especificada en la variable de entorno DLQ_LOCATION.
  2. En el árbol de carpetas anidadas que se construyó 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 verse como en el siguiente ejemplo:

    Archivos en la DLQ

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

    Es muy poco probable que haya errores reintentables, en especial si se usó un valor bajo para el parámetro dlqMaxRetryCount, pero, en general, los eventos que terminan en la DLQ no serán reintentables por los motivos descritos anteriormente.

  4. Puedes abortar la migración y reanudar el tráfico de aplicaciones a la base de datos de origen, abordar las restricciones de datos de Firestore en la base de datos de origen y volver a ejecutar todo el proceso de migración, o bien puedes abordar los problemas de datos con cada evento de la DLQ y volver a intentar el procesamiento de estos eventos.

Para cada fila de cada archivo de DLQ, puedes hacer lo siguiente:

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

  • Reasigna el documento _id de 0L a un nuevo Long o a un tipo de datos diferente, como String. Si se reasigna a un tipo de datos diferente, es posible que se requieran cambios en la lógica de la aplicación si las expectativas del código existente son que todos los _id sean Longs.

  • Los documentos que superan 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 controlar los datos.

  • Ignora el evento borrando la fila del archivo de la DLQ.

Para modificar los archivos de la DLQ, deberás descargar los archivos .json de forma local, modificar el contenido y volver a subirlos a la misma ubicación de Cloud Storage, lo que sobrescribirá el archivo original. Si todos los documentos a los que se hace referencia en el archivo se pueden excluir de forma segura de la migración, se puede borrar todo el archivo.

Después de modificar los archivos de la DLQ, puedes volver a ejecutar estos eventos a través de 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 no entregados:

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

¿Qué sigue?