Administra los riesgos de escalamiento

Cloud Tasks te permite enviar grandes volúmenes de tareas asíncronas mientras controlas la velocidad a la que el tráfico llega a tus colas y servicios downstream. Si aplicas patrones de aumento gradual y controles de frecuencia, puedes escalar las cargas de trabajo sin problemas y sin activar picos de latencia en la cola ni sobrecargar el destino cuando el tráfico aumenta más rápido de lo que la infraestructura puede adaptarse.

Descripción general

En este documento, se proporcionan lineamientos sobre las prácticas recomendadas para mantener un alto rendimiento de Cloud Tasks en las colas con mucho tráfico. Una cola de TPS alto es una cola que tiene 500 tareas creadas o enviadas por segundo (TPS) o más. Un grupo de colas de TPS alto es un conjunto contiguo de colas, por ejemplo, [queue0001, queue0002, …, queue0099], que tienen al menos 2,000 tareas creadas o enviadas por segundo en total. Puedes ver el TPS histórico de una cola o un grupo de colas con las métricas de Cloud Monitoring, api/request_count para las operaciones CreateTask y queue/task_attempt_count para los intentos de tareas. Las colas y los grupos de colas con mucho tráfico son propensos a dos clases generales de fallas:

La sobrecarga de la cola se produce cuando la creación y el envío de tareas a una cola o un grupo de colas individuales aumentan más rápido de lo que la infraestructura de la cola puede adaptarse. La infraestructura de Google usa capas adaptables que reasignan la carga de forma dinámica en función de los patrones de tráfico, y esta adaptación lleva tiempo. Del mismo modo, la sobrecarga del destino se produce cuando la tasa de envío de tareas provoca aumentos repentinos de tráfico en la infraestructura de destino descendente. En ambos casos, sigue un patrón de 500/50/5: cuando escales más allá de 500 TPS, aumenta el tráfico en no más del 50% cada 5 minutos.

A diferencia del patrón 500/50/5 para cargas de trabajo con TPS altas, el aumento inicial de la cola afecta a todas las colas cuando comienzan desde un estado inactivo o frío, incluidas las colas configuradas para tasas de envío moderadas. En este documento, se revisan diferentes situaciones que pueden generar riesgos de escalamiento y se proporcionan ejemplos de cómo administrar el aumento de la cola y aplicar el patrón 500/50/5.

Aumento inicial de la cola

El patrón 500/50/5 se aplica a las colas de TPS altas que ya operan en un estado estable. El aumento inicial de la cola es un mecanismo del sistema independiente que se aplica a todas las colas, incluidas las configuradas para tasas de envío moderadas, como de 20 a 100 TPS, a medida que pasan de un estado inactivo o frío a un funcionamiento en estado estable.

Una cola entra en un estado inactivo o frío en cualquiera de las siguientes situaciones:

  • La cola se creó recientemente o se reanudó después de pausarse.

  • La cola estuvo inactiva durante unos minutos sin envíos activos.

  • La cola se está recuperando después de retirarse de las respuestas de error HTTP 429 o 5xx descendentes. Para obtener más información sobre cómo la retirada por error afecta las tasas de envío, consulta Errores de retirada y tasas aplicadas.

Cuando las tareas llegan a una cola inactiva o fría, Cloud Tasks no las envía de inmediato con la tasa max_dispatches_per_second configurada. Para proteger los destinos downstream de aumentos repentinos de tráfico, Cloud Tasks comienza a enviar a una tasa de referencia baja, como alrededor de 1 TPS. Luego, aumenta de forma progresiva la tasa de envío aplicada en los intervalos de evaluación periódicos. La tasa aplicada sigue aumentando mientras la demanda de la cola permanezca saturada y los controladores de destino devuelvan respuestas HTTP 2xx. Según tu tasa objetivo, alcanzar valores altos de max_dispatches_per_second puede tardar varios minutos.

Si tu carga de trabajo envía tráfico con aumentos repentinos separados por períodos de inactividad breves de unos minutos o más, la cola se restablece a un estado frío entre las ráfagas y repite este proceso de aumento en cada ráfaga. Para minimizar las demoras en el aumento de las cargas de trabajo sensibles a las ráfagas, sigue estas prácticas recomendadas:

  • Mantén un flujo constante de tráfico de referencia para mantener activas las colas sensibles a la latencia entre ráfagas.

  • Reutiliza las colas existentes en lugar de borrarlas y volver a crearlas con frecuencia.

  • Aprovisiona suficiente capacidad de destino descendente para que los controladores devuelvan respuestas HTTP 2xx y eviten devolver respuestas de error HTTP 429 o 5xx que restablezcan la tasa de envío aplicada.

Diagnostica la limitación de la cola

Si tu cola envía tareas con una frecuencia inferior a la que configuraste en max_dispatches_per_second, verifica si el cuello de botella se debe a un aumento de la cola inactiva o en frío, a una retirada por congestión del destino o a límites de simultaneidad.

Aumento de la cola inactiva o fría

Es probable que la causa sea el aumento inicial de la cola si se cumplen todas las condiciones siguientes:

  • La cola se creó recientemente, se reanudó después de pausarse o estuvo inactiva durante unos minutos antes de que llegara el tráfico.
  • Los intentos de tareas se realizan correctamente sin errores de destino, lo que muestra response_code="OK" en la métrica de Monitoring cloudtasks.googleapis.com/queue/task_attempt_count.
  • Los envíos en curso permanecen por debajo de max_concurrent_dispatches, mientras que cloudtasks.googleapis.com/queue/depth o cloudtasks.googleapis.com/queue/task_attempt_delays se elevan. Al mismo tiempo, la tasa de envío en cloudtasks.googleapis.com/queue/task_attempt_count aumenta de forma progresiva en intervalos de evaluación periódicos.

Para obtener más información sobre las métricas de Monitoring, consulta Envía métricas a Monitoring.

Sobrecarga de destino y retirada por congestión

Cloud Tasks reduce de forma dinámica las tasas de envío si tu destino posterior devuelve respuestas de error HTTP 429 Too Many Requests o HTTP 5xx, como HTTP 503 Service Unavailable. Esta retirada por congestión evita la sobrecarga del destino.

Para verificar si los errores de destino hacen que Cloud Tasks limite los envíos, consulta la métrica de Monitoring cloudtasks.googleapis.com/queue/task_attempt_count agrupada por la etiqueta response_code. Si el registro de colas está habilitado, también puedes inspeccionar los registros de respuesta de intentos en el Explorador de registros:

resource.type="cloud_tasks_queue"
jsonPayload.attemptResponseLog.status!="OK"

En response_code y jsonPayload.attemptResponseLog.status, Cloud Tasks registra códigos de estado de gRPC canónicos en lugar de códigos de estado HTTP numéricos. Por ejemplo, HTTP 429 se asigna a RESOURCE_EXHAUSTED, HTTP 503 se asigna a UNAVAILABLE, HTTP 500 se asigna a INTERNAL, y HTTP 504 o un tiempo de espera se asigna a DEADLINE_EXCEEDED.

Si observas estados de error de servidor RESOURCE_EXHAUSTED, UNAVAILABLE o de otro tipo en el destino, escala verticalmente las instancias de servicio de destino o aumenta la simultaneidad de destino antes de aumentar los límites de envío de la cola.

Para obtener más información sobre cómo habilitar los registros de colas, consulta Usa Cloud Logging con colas.

Cuello de botella de simultaneidad

Según la ley de Little, la latencia objetivo descendente limita la capacidad de procesamiento máxima de envío:

Max Throughput (tasks/sec) = min(
  max_dispatches_per_second,
  max_concurrent_dispatches / Downstream Latency in seconds
)

Por ejemplo, si la latencia de ejecución descendente es de 2 segundos y max_concurrent_dispatches se establece en 100, la capacidad de procesamiento se limita a 50 tareas por segundo, incluso si max_dispatches_per_second se configura en 500.

Para diagnosticar si la simultaneidad es el cuello de botella, divide max_concurrent_dispatches por la latencia de respuesta del destino registrada en el campo jsonPayload.attemptResponseLog.attemptDuration en Logging. Compara este umbral calculado con tu tasa de envío real en la métrica de Monitoring cloudtasks.googleapis.com/queue/task_attempt_count. Si los envíos reales se estabilizan cerca de este umbral mientras cloudtasks.googleapis.com/queue/depth o cloudtasks.googleapis.com/queue/task_attempt_delays aumentan, realiza una de las siguientes acciones:

  • Si tu destino downstream tiene capacidad libre, como cuando las tareas pasan la mayor parte de su duración esperando en E/S externas, aumenta max_concurrent_dispatches.
  • Si tu destino downstream ya tiene un uso de recursos alto, aumentar max_concurrent_dispatches puede empeorar la sobrecarga del destino. En su lugar, escala horizontalmente tus instancias de destino o reduce la latencia de ejecución del controlador.

Sobrecarga de la cola

Las colas o los grupos de colas pueden sobrecargarse en cualquier momento en que el tráfico aumente de forma repentina. Como resultado, estas colas pueden experimentar lo siguiente:

  • Mayor latencia en la creación de tareas
  • Mayor frecuencia de errores en la creación de tareas
  • Menor frecuencia de envío

Para defenderte de esto, establece controles en cualquier situación en la que la tasa de creación o envío de una cola o un grupo de colas pueda aumentar de forma repentina. Comienza con un máximo de 500 operaciones por segundo en una cola o un grupo de colas en frío y, luego, aumenta el tráfico un 50% cada 5 minutos. En teoría, puedes aumentar a 740,000 operaciones por segundo después de 90 minutos con este programa de aumento gradual. Existen varias circunstancias en las que esto puede ocurrir.

Por ejemplo:

  • Cuando lanzas nuevas funciones que hacen un uso intensivo de Cloud Tasks
  • Cuando transfieres tráfico de una cola a otra
  • Cuando se rebalancea el tráfico después de aumentar o reducir la cantidad de colas
  • Cuando ejecutas trabajos por lotes que inyectan una gran cantidad de tareas

En estos y otros casos, sigue el patrón 500/50/5.

Usa la división del tráfico de App Engine

Si una app de App Engine crea las tareas, puedes aprovechar la división del tráfico de App Engine (entorno estándar de App Engine o entorno flexible de App Engine) para suavizar los aumentos de tráfico. Si divides el tráfico entre versiones (entorno estándar o entorno flexible), puedes aumentar las solicitudes con administración de frecuencia con el tiempo para proteger el estado de la cola. Por ejemplo, considera el caso de aumentar el tráfico a un grupo de colas recién expandido: deja que [queue0000, queue0199] sea una secuencia de colas de TPS altas que reciben 100,000 creaciones de TPS en total en el momento de mayor actividad.

Supongamos que [cola0200, cola0399] es una secuencia de colas nuevas. Después de cambiar todo el tráfico, la cantidad de colas en la secuencia se duplica y el nuevo rango de colas recibe el 50% del tráfico total de la secuencia.

Cuando implementes la versión que aumenta la cantidad de colas, aumenta de forma gradual el tráfico a la versión nueva y, por lo tanto, a las colas nuevas, con la división del tráfico:

  • Comienza a transferir el 1% del tráfico a la nueva versión. Por ejemplo, el 50% del 1% de 100,000 TPS genera 500 TPS para el conjunto de colas nuevas.
  • Cada 5 minutos, aumenta un 50% el tráfico enviado a la versión nueva, como se detalla en la siguiente tabla:
Minutos desde el comienzo de la implementación % del tráfico total que se transfirió a la versión nueva % del tráfico total que se envía a las colas nuevas % del tráfico total que se envía a las colas antiguas
0 1.0 0.5 99.5
5 1.5 0.75 99.25
10 2.3 1.15 98.85
15 3.4 1.7 98.3
20 5.1 2.55 97.45
25 7.6 3.8 96.2
30 11.4 5.7 94.3
35 17.1 8.55 91.45
40 25.6 12.8 87.2
45 38.4 19.2 80.8
50 57.7 28.85 71.15
55 86.5 43.25 56.75
60 100 50 50

Picos de tráfico generados por lanzamientos

Cuando se lanza una versión que aumenta de forma significativa el tráfico a una cola o un grupo de colas, el lanzamiento gradual es, de nuevo, un mecanismo importante para suavizar los aumentos. Lanza tus instancias de forma gradual para que el lanzamiento inicial no supere las 500 operaciones por segundo en total en las colas nuevas, y aumenta no más del 50% cada 5 minutos.

Nuevas colas o grupos de colas con un alto nivel de TPS

Las colas recién creadas son especialmente vulnerables. Los grupos de colas, por ejemplo, [queue0000, queue0001, …, queue0199], son tan sensibles como las colas individuales durante las etapas iniciales del lanzamiento. Para estas colas, el lanzamiento gradual es una estrategia importante. Lanza servicios nuevos o actualizados que creen colas o grupos de colas con TPS altas en etapas. Mantén la carga inicial por debajo de 500 TPS y, luego, aumenta la carga en un 50% o menos con intervalos de al menos 5 minutos.

Grupos de colas recién ampliados

Cuando aumentes la capacidad total de un grupo de colas, por ejemplo, expandiendo [queue0000-queue0199 a queue0000-queue0399], sigue el patrón 500/50/5. En los procedimientos de lanzamiento, los grupos de colas nuevos se comportan de la misma manera que las colas individuales. Aplica el patrón 500/50/5 al nuevo grupo en su totalidad, no solo a las colas individuales dentro del grupo.

Para estas expansiones de grupos de colas, el lanzamiento gradual es una estrategia importante. Si el origen de tu tráfico es App Engine, puedes usar la división del tráfico. Cuando migres tu servicio para agregar tareas a la mayor cantidad de colas, implementa tus instancias de forma gradual para que el lanzamiento inicial no supere las 500 operaciones totales en las colas nuevas y no aumentes el tráfico en más de un 50% cada 5 minutos.

Expansión de grupos de colas en caso de emergencia

En ocasiones, es posible que desees expandir un grupo de colas existente, por ejemplo, porque esperas que se agreguen tareas al grupo de colas más rápido de lo que el grupo puede enviarlas. Si distribuyes los nombres de las colas nuevas de manera uniforme entre los nombres de las colas existentes en orden lexicográfico, puedes enviar tráfico de inmediato a esas colas. Asegúrate de que no haya más de un 50% de colas intercaladas nuevas y de que el tráfico a cada cola sea inferior a 500 TPS. Este método es una alternativa al uso de la división del tráfico y el lanzamiento gradual.

Para lograr este tipo de nombres intercalados, agrega un sufijo a las colas que terminan en números pares. Por ejemplo, si tienes 200 colas existentes [queue0000-queue0199] y quieres crear 100 colas nuevas, elige [queue0000a, queue0002a, queue0004a, …, queue0198a] como los nombres de las colas nuevas, en lugar de [queue0200-queue0299].

Si necesitas un aumento mayor, puedes intercalar hasta un 50% más de colas cada 5 minutos.

Colas de tareas por lotes o a gran escala

Cuando necesites agregar una gran cantidad de tareas, por ejemplo, millones o miles de millones, puede ser útil un patrón de inserción doble. En lugar de crear tareas a partir de un solo trabajo, usa una cola de inyectores. Cada tarea que se agrega a la cola del inyector se distribuye y agrega 100 tareas a la cola o al grupo de colas correspondiente. Puedes acelerar la cola del inyector con el tiempo; por ejemplo, comienza con 5 TPS para generar 500 TPS en la cola o el grupo de colas de destino y, luego, aumenta la tasa en un 50% cada 5 minutos.

Tareas con nombre

Cuando creas una tarea nueva, Cloud Tasks le asigna un nombre único de forma predeterminada. Puedes asignar tu propio nombre a una tarea con el parámetro name. Sin embargo, esto genera una sobrecarga de rendimiento significativa, lo que implica mayores latencias y un posible aumento de las frecuencias de error asociadas con las tareas nombradas. Los nombres de tareas secuenciales, como las marcas de tiempo, pueden aumentar esta sobrecarga de forma significativa.

Si asignas tus propios nombres, usa un prefijo bien distribuido para los nombres de las tareas, como un hash del contenido. Para obtener más información sobre cómo asignar un nombre a una tarea, consulta la referencia del campo Task.name.

Sobrecarga del objetivo

Cloud Tasks puede sobrecargar los servicios y recursos downstream que usas, como App Engine, Firestore en modo Datastore (Datastore) y tu red, si los envíos de colas aumentan de forma repentina. Si se acumuló una lista de tareas pendientes, reactivar esas colas puede sobrecargar estos servicios. Para defenderte de la sobrecarga de destino, sigue el patrón 500/50/5: si una cola envía más de 500 TPS, aumenta el tráfico activado por una cola en no más del 50% cada 5 minutos. Para supervisar los aumentos de tráfico de forma proactiva, usa las métricas de Monitoring. Puedes usar las alertas de Monitoring para detectar situaciones potencialmente peligrosas.

Reactivar o reanudar las colas con TPS altas

Cuando reanudas una cola detenida, Cloud Tasks aplica el aumento inicial de la cola y aumenta de forma gradual la tasa de envío desde un valor de referencia bajo hacia la tasa max_dispatches_per_second configurada de la cola. Sin embargo, si se acumula una gran cantidad de tareas pendientes en una cola de TPS alta o en varias colas que reanudas al mismo tiempo, la tasa de envío puede seguir aumentando más rápido de lo que pueden escalar los servicios de destino downstream. Para evitar la sobrecarga del destino cuando se reanudan las colas con una gran cantidad de tareas pendientes, escalona el momento en que reanudas varias colas. Como alternativa, reduce temporalmente la tasa de max_dispatches_per_second y auméntala de forma gradual siguiendo el patrón 500/50/5. Para obtener más información sobre cómo Cloud Tasks limita y aumenta los envíos cuando se reanudan las colas, consulta Errores de retirada y tasas aplicadas de manera forzosa.

Tareas programadas en masa

La gran cantidad de tareas programadas para enviarse al mismo tiempo también puede introducir un riesgo de sobrecarga del destino. Si necesitas iniciar una gran cantidad de tareas a la vez, considera usar controles de frecuencia de cola para aumentar la frecuencia de envío de forma gradual o aprovisionar la capacidad de destino con anticipación.

Fan-outs aumentados

Cuando actualizas los servicios que llama Cloud Tasks, aumentar la cantidad de llamadas remotas puede crear riesgos de producción. Por ejemplo, supongamos que las tareas en una cola de TPS alta llaman al controlador /task-foo. Una versión nueva puede aumentar de forma significativa el costo de llamar a /task-foo si, por ejemplo, esa versión nueva agrega varias llamadas costosas de Datastore al controlador. El resultado neto de un lanzamiento de este tipo es un aumento masivo del tráfico de Datastore que se relaciona de inmediato con los cambios en el tráfico de los usuarios. Usa el lanzamiento gradual o la división del tráfico para administrar el aumento.

Reintentos

Tu código puede reintentar una llamada a la API de Cloud Tasks cuando se produce un error. Sin embargo, cuando una proporción significativa de solicitudes falla con errores del servidor, una tasa de reintentos alta puede sobrecargar aún más las colas y ralentizar la recuperación. Limita la cantidad de tráfico saliente si tu cliente detecta que una proporción significativa de solicitudes falla con errores del servidor. Por ejemplo, puedes usar el algoritmo de limitación adaptable que se describe en el capítulo Controla la sobrecarga del libro Ingeniería de confiabilidad de sitios. Las bibliotecas cliente de gRPC de Google implementan una variación de este algoritmo.