Administra riesgos de escalamiento

La infraestructura de Google está diseñada para operar de forma elástica a gran escala. La mayoría de las capas puede adaptarse a demandas de tráfico crecientes hasta alcanzar una escala masiva. Uno de los patrones de diseño esenciales que hacen posible esto son las capas adaptables, que son componentes de la infraestructura que reasignan cargas de forma dinámica según los patrones de tráfico. Sin embargo, esta adaptación requiere tiempo. Como Cloud Tasks permite enviar volúmenes de tránsito realmente altos, expone riesgos de producción en situaciones en las que el tráfico puede aumentar a una velocidad tal que la infraestructura no llega a adaptarse.

Resumen

En este documento, se brindan lineamientos sobre las recomendaciones para mantener un alto rendimiento de Cloud Tasks con colas de alto tráfico. Una cola de alto TPS es una cola que tiene 500 tareas creadas o despachadas por segundo (TPS) o más. Un grupo de colas de alto TPS es un conjunto contiguo de colas (por ejemplo [cola0001, cola0002, …, cola0099]) en el que se crean o envían, por lo menos, 2,000 tareas en total. El TPS histórico de una cola o grupo de colas es visible mediante las métricas de Stackdriver, api/request_count para las operaciones "CreateTask" y queue/task_attempt_count para los intentos de realizar tareas. Las colas y los grupos de colas de alto tráfico son propensos a dos clases amplias de falla:

La sobrecarga de la cola ocurre cuando se crean y envían tareas a una cola o un grupo de colas individual tan rápidamente que la infraestructura no puede adaptarse. De manera similar, la sobrecarga del objetivo ocurre cuando la frecuencia con la que se envían las tareas genera picos de tráfico en la infraestructura objetivo descendente. En ambos casos, recomendamos seguir un patrón 500/50/5: Cuando se aumenta la escala a más de 500 TPS, el tráfico no debería aumentar más de un 50% cada 5 minutos. En este documento, se revisan las distintas situaciones que pueden introducir riesgos de escalamiento y se brindan ejemplos de cómo aplicar este patrón.

Sobrecarga de la cola

Las colas o los grupos de colas pueden sobrecargarse siempre que el tráfico aumente repentinamente. Como consecuencia, estas colas pueden experimentar los siguientes problemas:

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

A fin de prevenir estos problemas, recomendamos establecer controles en cualquier situación en la que la frecuencia de creación o envío de una cola o un grupo de colas pueda aumentar repentinamente. Recomendamos un máximo de 500 operaciones por segundo para una cola o un grupo de colas no preparados, y luego aumentar el tráfico en un 50% cada 5 minutos. En teoría, puedes alcanzar 740,000 operaciones por segundo después de utilizar este programa de aceleración por 90 minutos. Hay varias circunstancias en las que podría suceder esto.

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.

Cómo usar la división de tráfico de App Engine

Si una aplicación de App Engine está creando las tareas, puedes aprovechar la división de tráfico de App Engine (Standard/Flexible) para suavizar los incrementos de tráfico. Cuando divides el tráfico entre distintas versiones (Standard/Flexible), las solicitudes que necesitan que se controle su frecuencia pueden aumentarse de forma paulatina para evitar que la cola deje de funcionar correctamente. Por ejemplo, considera una situación en la que se debe aumentar el tráfico a un grupo de colas que acaba de ampliarse: Supongamos que [cola0000, cola0199] es una secuencia de colas de alto TPS que reciben un total de 100,000 creaciones de TPS en el punto máximo.

Supongamos que [cola0200, cola0399] es una secuencia de colas nuevas. Una vez que todo el tráfico se redistribuya, la cantidad de colas de la secuencia se habrá duplicado y las colas nuevas estarán recibiendo el 50% del tráfico total de la secuencia.

Cuando implementes la versión que aumenta la cantidad de colas, aumenta gradualmente el tráfico hacia la versión nueva (y, por consiguiente, a las colas nuevas) mediante la división de 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 equivale a 500 TPS para el conjunto de colas nuevas.
  • Cada 5 minutos, aumenta el tráfico que se envía a la nueva versión en un 50%, tal 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 lances una versión que aumente el tráfico a una cola o un grupo de colas significativamente, también es importante que lo hagas gradualmente a fin de suavizar los aumentos. Lanza tus instancias gradualmente, de modo tal que el lanzamiento inicial no supere un total de 500 operaciones a las colas nuevas y el aumento no sea mayor al 50% cada 5 minutos.

Colas o grupos de colas nuevos de alto TPS

Las colas recién creadas son especialmente vulnerables. Los grupos de colas, como [cola0000, cola0001, …, cola0199], son igual de sensibles que las colas individuales durante las etapas de implementación inicial. En el caso de estas colas, el lanzamiento gradual es una estrategia importante. Cuando lances servicios nuevos o actualizados que creen colas o grupos de colas de alto TPS, hazlo por etapas, de modo que la carga inicial sea inferior a 500 TPS y se apliquen aumentos del 50% o menos cada 5 minutos o más.

Grupos de colas recién ampliados

Cuando aumentes la capacidad total de un grupo de colas (por ejemplo, si amplías [cola0000-cola0199 a cola0000-cola0399]), sigue el patrón 500/50/5. Es importante tener en cuenta que, para los procedimientos de lanzamiento, los grupos de colas nuevos funcionan exactamente igual que las colas. Aplica el patrón 500/50/5 a los grupos de colas nuevos en conjunto, no solo a las colas individuales que integran el grupo. Para estas ampliaciones de grupos de colas, el lanzamiento gradual también es una estrategia importante. Si el origen de tu tráfico es App Engine, puedes usar la división de tráfico (consulta Picos de tráfico generados por lanzamientos). Si vas a migrar tu servicio a fin de agregarles tareas al mayor número de colas, lanza tus instancias gradualmente, de modo tal que el lanzamiento inicial no supere un total de 500 operaciones a las colas nuevas y el aumento no sea mayor al 50% cada 5 minutos.

Expansión de grupos de colas en caso de emergencia

Ocasionalmente, es posible que necesites ampliar un grupo de colas existente (por ejemplo, porque se espera que se agreguen tareas a un grupo de colas más rápido de lo que el grupo puede enviarlas). Si los nombres de las colas nuevas se distribuyen de manera uniforme entre los nombres de las colas existentes cuando se ordenan lexicográficamente, el tráfico se puede enviar inmediatamente a esas colas, siempre que no haya más de un 50% de colas intercaladas nuevas y el tráfico a cada cola sea menor de más de 500 TPS. Este método es una alternativa al uso de la división del tráfico y el lanzamiento gradual, como se describe en las secciones anteriores.

Para lograr que los nombres estén intercalados de esta forma, puedes agregar un sufijo a las colas que terminan en números pares. Por ejemplo, si tienes 200 colas existentes [cola0000-cola0199] y quieres crear 100 colas nuevas, elige [cola0000a, cola0002a, cola0004a, …, cola0198a] como los nombres de las colas nuevas, en lugar de [cola0200-cola0299].

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

Colas a las que se agregan tareas por lotes o a gran escala

Cuando se necesita agregar una gran cantidad de tareas (por ejemplo, millones o miles de millones), puede ser útil emplear un patrón de inyección doble. En lugar de crear tareas a partir de un solo trabajo, usa una cola de inyección. Cada tarea que se agregue a la cola de inyección se despliega con una operación fan-out y agrega 100 tareas a la cola o el grupo de colas de destino. La cola de inyección puede acelerarse con el tiempo. Por ejemplo, podría comenzar a 5 TPS y luego aumentar en un 50% cada 5 minutos.

Tareas con nombre

Cuando creas una tarea nueva, Cloud Tasks le asigna un nombre único de manera predeterminada. Si deseas asignarle un nombre específico a una tarea, puedes usar 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. Estos costos pueden aumentar mucho si las tareas reciben nombres secuenciales (por ejemplo, con marcas de tiempo). Por lo tanto, si asignas tus propios nombres, te recomendamos que uses un prefijo bien distribuido para los nombres de tareas, como un hash del contenido. Consulta la documentación para obtener más información sobre cómo nombrar una tarea.

Sobrecarga del objetivo

Cloud Tasks puede sobrecargar otros servicios que estás usando, como App Engine, Datastore y el uso de tu red, si los despachos de una cola aumentan drásticamente en un período corto. Si se acumuló una gran cantidad de tareas pendientes, reanudar esas colas podría generar una sobrecarga de estos servicios. La defensa recomendada es el mismo patrón 500/50/5 que sugerimos para la sobrecarga de las colas: si una cola envía más de 500 TPS, aumenta el tráfico que activa una cola en no más del 50% cada 5 minutos. Usa las métricas de Stackdriver para supervisar activamente tus aumentos de tráfico. Puedes usar alertas de Stackdriver para detectar situaciones potencialmente peligrosas.

Cómo reanudar colas de alto TPS

Cuando una cola o una serie de colas se reanuda o rehabilita, las colas vuelven a realizar envíos. Si la cola tiene muchas tareas, es posible que la frecuencia de envío de la cola que acaba de habilitarse aumente drásticamente de 0 TPS a la capacidad completa de la cola. A fin de hacer un aumento controlado, reanuda las colas de manera escalonada o controla las frecuencias de envío de las colas con maxDispatchesPerSecond de Cloud Tasks.

Tareas programadas en masa

Si tienes una gran cantidad de tareas programadas para enviarse al mismo tiempo, también existe riesgo de que se sobrecargue el objetivo. Si necesitas iniciar una gran cantidad de tareas a la vez, tal vez sea conveniente que uses los controles de la frecuencia de las colas para aumentar la frecuencia de envío gradualmente o que incrementes la capacidad del objetivo de manera explícita.

Fan-outs aumentados

Cuando actualices servicios que se ejecutan mediante Cloud Tasks, aumentar la cantidad de llamadas remotas puede crear riesgos de producción. Por ejemplo, supongamos que las tareas en una cola de alto TPS llaman al controlador /task-foo. Una nueva versión podría aumentar significativamente el costo de llamar a /task-foo si, por ejemplo, esa nueva versión agrega varias llamadas costosas a Datastore al controlador. El resultado neto de ese lanzamiento sería un aumento masivo en el tráfico de Datastore que se relaciona inmediatamente con cambios en el tráfico de usuarios. Para manejar el aumento paulatino, usa un lanzamiento gradual o divide el tráfico.

Reintentos

Tu código puede reintentar una llamada a la API de Cloud Tasks cuando se produce un error. Sin embargo, si falla una proporción significativa de tus solicitudes con errores del servidor, podría producirse una frecuencia elevada de reintentos que sobrecargue tus colas aún más y haga que se recuperen más lentamente. Por lo tanto, recomendamos que pongas un límite a la cantidad de tráfico de salida si tu cliente detecta que una proporción significativa de las solicitudes está fallando con errores del servidor. Por ejemplo, puedes usar el algoritmo de regulación adaptable que se describe en el capítulo Handling Overload del libro Site Reliablity Engineering). Las bibliotecas cliente de gRPC de Google implementan una variante de este algoritmo.