Las tareas de un trabajo o incluso las ejecuciones de un trabajo pueden fallar por varios motivos. En esta página se incluyen prácticas recomendadas para gestionar estos errores, centradas en los reinicios de tareas y en la creación de puntos de control de trabajos.
Usar reintentos de tareas
Las tareas de un trabajo individual pueden fallar por varios motivos, como problemas con las dependencias de las aplicaciones, las cuotas o incluso eventos internos del sistema. A menudo, estos problemas son transitorios y la tarea se completará después de reintentarla.
De forma predeterminada, cada tarea se volverá a intentar automáticamente hasta 3 veces. De esta forma, te aseguras de que un trabajo se complete aunque se produzcan fallos transitorios en las tareas. También puedes personalizar el número máximo de reintentos. Sin embargo, si cambia el valor predeterminado, debe especificar al menos un reintento.
Planificar los reinicios de tareas de trabajos
Haz que tus tareas sean idempotentes para que, si se reinicia una tarea, no se produzcan resultados corruptos o duplicados. Es decir, escribe una lógica repetible que tenga el mismo comportamiento para un conjunto de entradas determinado, independientemente de cuántas veces se repita o de cuándo se ejecute.
Escribe la salida en una ubicación diferente a la de los datos de entrada para que estos no se modifiquen. De esta forma, si la tarea se vuelve a ejecutar, puede repetir el proceso desde el principio y obtener el mismo resultado.
Evita duplicar los datos de salida reutilizando el mismo identificador único o comprobando si ya existen. Los datos duplicados representan un error en los datos a nivel de colección.
Usar la creación de puntos de control
Cuando sea posible, crea puntos de control en tus trabajos para que, si una tarea se reinicia tras un error, pueda continuar donde lo dejó en lugar de volver a empezar. De esta forma, tus tareas se completarán más rápido y se minimizarán los costes innecesarios.
Escribe periódicamente resultados parciales y una indicación del progreso realizado en una ubicación de almacenamiento persistente, como Cloud Storage o una base de datos. Cuando empiece la tarea, busca resultados parciales al inicio. Si se encuentran resultados parciales, empieza el procesamiento donde lo dejaste.
Si tu trabajo no se presta a la creación de puntos de control, considera la posibilidad de dividirlo en partes más pequeñas y ejecutar un mayor número de tareas.
Ejemplo de punto de control 1: cálculo de Pi
Si tienes un trabajo que ejecuta un algoritmo recursivo, como calcular Pi con muchos decimales, y usa el paralelismo con el valor 1:
- Escribe tu progreso cada 10 minutos o con la frecuencia que te permita tu tolerancia a la pérdida de trabajo en un objeto de
pi-progress.txt
Cloud Storage. - Cuando se inicia una tarea, consulta el objeto
pi-progress.txt
y carga el valor como punto de partida. Usa ese valor como entrada inicial de tu función. - Escribe el resultado final en Cloud Storage como un objeto llamado
pi-complete.txt
para evitar duplicados mediante la ejecución paralela o repetida, opi-complete-DATE.txt
para diferenciarlo por fecha de finalización.
Ejemplo de punto de control 2: procesar 10.000 registros de Cloud SQL
Si tienes un trabajo que procesa 10.000 registros en una base de datos relacional, como Cloud SQL, haz lo siguiente:
- Obtener los registros que se van a procesar con una consulta SQL, como
SELECT * FROM example_table LIMIT 10000
- Escribe los registros actualizados en lotes de 100 para que no se pierda una cantidad significativa de trabajo de procesamiento si se produce una interrupción.
- Cuando se escriban los registros, anota cuáles se han procesado. Puede añadir una columna booleana "processed" a la tabla, que solo se establece en 1 si se confirma el procesamiento.
- Cuando se inicia una tarea, la consulta utilizada para recuperar elementos para el procesamiento debe añadir la condición processed = 0.
- Además de los reintentos limpios, esta técnica también permite dividir el trabajo en tareas más pequeñas, como modificar la consulta para seleccionar 100 registros a la vez:
LIMIT 100 OFFSET $CLOUD_RUN_TASK_INDEX*100
. Después, se ejecutan 100 tareas para procesar los 10.000 registros.CLOUD_RUN_TASK_INDEX
es una variable de entorno integrada que se encuentra en el contenedor que ejecuta los trabajos de Cloud Run.
Si juntamos todas estas partes, la consulta final podría tener este aspecto:
SELECT * FROM example_table WHERE processed = 0 LIMIT 100 OFFSET $CLOUD_RUN_TASK_INDEX*100
Siguientes pasos
- Para crear una tarea de Cloud Run, consulta Crear tareas.
- Para ejecutar un trabajo, consulta Ejecutar trabajos.
- Para ejecutar una tarea según una programación, consulta Ejecutar tareas según una programación.