Blog de Amazon Web Services (AWS)

Escalado de aplicaciones con AWS Lambda

Por Daniel Abib, Arquitecto de soluciones empresariales, FSI – LATAM

 

El servicio AWS Lambda está diseñado para implementar tareas informáticas a corto plazo basadas en eventos que no conservan ni dependen del estado entre las invocaciones. El servicio AWS Lambda invoca su código de lógica de negocio a solicitud en respuesta a eventos de otros servicios de AWS, solicitudes a través de la CLI de AWS o los SDK de AWS. El código se puede ejecutar en hasta 15 minutos en una sola llamada y una sola función puede utilizar de 128 MB a 10.240 MB de memoria.

La concurrencia es el número de solicitudes que su función de AWS Lambda ejecuta al mismo tiempo. Para cada solicitud simultánea, el servicio AWS Lambda aprovisiona una instancia independiente de su entorno de ejecución. A medida que sus funciones reciben más solicitudes, AWS Lambda se encarga automáticamente de escalar el número de entornos de ejecución hasta que alcance el límite de cuota de su cuenta. De forma predeterminada, AWS Lambda proporciona a su cuenta un límite total de 1000 entornos de ejecución simultáneos para todas las funciones de una región. Sin embargo, para satisfacer las necesidades específicas de sucuenta, puedes solicitar un aumento de cuota y configurar controles de concurrencia a nivel de función para que sus funciones críticas no se vean restringidas.

En este blog se explica la concurrencia y el escalado de funciones en AWS Lambda. Al final de este blog, que se basó en la documentación oficial de AWS, podrá entender cómo calcular la concurrencia, ver las dos opciones principales de control de concurrencia(reservadas y aprovisionadas), estimar la configuración de control de la concurrencia adecuada y ver las métricas para una mayor optimización.

 

Comprender y visualizar la concurrencia

AWS Lambda invoca su función en un entorno de ejecución seguro y aislado. Para cumplir con una solicitud, AWS Lambda debe inicializar primero un entorno de ejecución (la fase de inicio inicial) antes de usarlo para invocar su función (la fase de invocación).

En la fase de inicio (inicialización), AWS Lambda crea o descongela un entorno de ejecución con los recursos configurados, descarga el código de la función y todas las capas, inicializa todas las extensiones y el tiempo de ejecución y, a continuación, ejecuta el código de inicialización de la función (el código que está fuera del controlador principal).  El inicio se ejecuta durante la primera llamada o antes de las llamadas a funciones si ha activado la concurrencia aprovisionada. Este es el mejor momento para abrir conexiones a bases de datos o recursos externos, ya que solo se ejecutarán una .

 

El diagrama anterior utiliza un rectángulo para representar un único entorno de ejecución. Cuando la función recibe su primera solicitud (representada por el círculo amarillo con la etiqueta 1), AWS Lambda crea un nuevo entorno de ejecución y ejecuta el código fuera del controlador principal durante la fase Inic. (puesta en marcha). Luego, AWS Lambda ejecuta el código del controlador principal de la función durante la fase de invocación.  Durante todo este proceso, este entorno de ejecución está ocupado y no puede procesar otras solicitudes.

Cuando AWS Lambda termine de procesar la primera solicitud, ese entorno de ejecución podrá procesar solicitudes adicionales para la misma función. Para solicitudes posteriores, AWS Lambda no necesita reiniciar el entorno.

 

En el diagrama anterior, AWS Lambda reutiliza el entorno de ejecución para gestionar la segunda solicitud (representada por el círculo amarillo con la etiqueta 2), pero observe que la fase de inicio (inicial) no se vuelve a ejecutar.

Hasta ahora, nos hemos centrado en una sola instancia de su entorno de ejecución (es decir, una concurrencia de 1). En la práctica, es posible que AWS Lambda necesite aprovisionar varias instancias del entorno de ejecución en paralelo para gestionar todas las solicitudes entrantes.

Cuando su función recibe una nueva solicitud, puede suceder una de estas dos cosas:

  • Si hay disponible una instancia de ejecución preinicializada, AWS Lambda la utilizará para procesar la solicitud.
  • De lo contrario, AWS Lambda creará una nueva instancia de ejecución para procesar la solicitud.

Por ejemplo, analicemos qué sucede cuando sufunción recibe 10 solicitudes:

 

En el diagrama anterior, cada plano horizontal representa una única instancia del entorno de ejecución (etiquetada de A a F).

A medida que su función recibe más solicitudes simultáneas, AWS Lambda aumenta el número de instancias del entorno de ejecución en respuesta.

En resumen, la concurrencia de su función es el número de solicitudes simultáneas que gestiona al mismo tiempo. En respuesta al aumento de la concurrencia de la función, AWS Lambda suministra más instancias del entorno de ejecución para satisfacer la demanda de solicitudes.

 

Cómo calcular la concurrencia

En general, la concurrencia de un sistema es la capacidad de procesar más de una tarea simultáneamente. En AWS Lambda, la concurrencia es el número de solicitudes que su función gestiona al mismo tiempo. Una forma rápida y práctica de medir la concurrencia de una función de AWS Lambda consiste en utilizar la siguiente fórmula:

Concurrencia = (promedio de solicitudes por segundo) * (promedio de la duración de la solictud en segundos)

La concurrencia difiere de las solicitudes por segundo (TPS).   Por ejemplo, supongamos que la función recibe en promedio 100 solicitudes por segundo. Si el promedio de la duración de las solicitudes es de 1 segundo, es cierto que la concurrencia también es de 100:

Concurrencia = (100 solicitudes/segundo) * (1 segundo/solicitud) = 100

Sin embargo, si el promedio de la duración de las solicitudes es de 500 ms, la concurrencia será de 50:

Concurrencia = (100 solicitudes/segundo) * (0.  5 segundos/solicitud) = 50

¿Qué significa una concurrencia de 50 en la práctica? Si el promedio de la duración de las solicitudes es de 500 ms, puedes pensar que una instancia de sufunción puede gestionar 2 solicitudes por segundo. Luego, se necesitan 50 instancias de sufunción para gestionar una carga de 100 solicitudes por segundo. Una concurrencia de 50 significa que AWS Lambda debe aprovisionar 50 instancias en tiempo de ejecución para gestionar esta carga de trabajo de manera eficiente y sin ninguna limitación. A continuación se explica cómo expresar esto en forma de ecuación:

Concurrencia = (100 solicitudes/segundo)/(2 solicitudes/segundo) = 50

Si su función recibe el doble de solicitudes (200 solicitudes por segundo) pero solo requiere la mitad del tiempo para procesar cada solicitud (250 ms), la concurrencia seguirá siendo de 50:

Concurrencia = (200 solicitudes/segundo) * (0.  25 segundos/solicitud) = 50

 

Concurrencia reservada y Concurrenciaaprovisionada

De forma predeterminada, su cuenta tiene un límite de concurrencia de 1000 en todas las funciones de una región. Sus funciones comparten este grupo de 1000 concurrencias bajo demanda. Su función se ralentiza si se queda sin concurrencia disponible.

Algunas de sus funciones pueden ser más críticas que otras. Como resultado, debe definir la configuración de concurrencia para garantizar que las funciones críticas obtengan la concurrencia que necesitan. Hay dos tipos de controles de concurrencia disponibles: concurrencia reservada y concurrencia aprovisionada.

  • Usa la concurrencia reservada para reservar para reservar una parte de la concurrencia de su cuenta para una función. Esto es útil si no desea que otras funciones ocupen toda la simultaneidad no reservada disponible.
  • Utilice la concurrencia aprovisionada para para preinicializar una cantidad de instancias de entorno para una función. Esto es útil para reducir las latencias de arranque en frío.

 

Concurrencia reservada

Si quiere asegurarse de que hay una cantidad determinada de concurrencia disponible para su función en un momento dado, utilice la concurrencia reservada.

La concurrencia reservada es el número máximo de instancias simultáneas que deses asignar a su función. Cuando dedica una concurrencia reservada a una función, ninguna otra función puede utilizar esa concurrencia. En otras palabras, la configuración de concurrencia reservada puede afectar al grupo de concurrencia que está disponible para otras funciones. Las funciones que no tienen concurrencia reservada comparten el resto de la concurrenciaƒ sin reservas.

La configuración de la concurrencia reservada se incluye en el límite general de concurrencia de la cuenta. Crear un concurrencia reservado para un puesto no conlleva ningún coste.

Para entender mejor la concurrencia reservada, considere el siguiente diagrama:

 

En este diagrama, el límite de concurrencia de sucuenta para todas las funciones de esa región está en el límite predeterminado de 1000. Supongamos que tiene dos funciones críticas, la función azul y la función naranja, que normalmente esperan obtener grandes volúmenes de citaciones. Decides dar 400 unidades de concurrenciareservadas a la función azul y 400 unidades de concurrenciareservadas a la función naranja. En este ejemplo, todas las demás funciones de sucuenta deben compartir las 200 unidades restantes de la concurrencia sin reservas.

El diagrama tiene 5 puntos de interés:

  • En T1, tanto la función naranja como la función azul comienzan a recibir solicitudes. Cada función comienza a utilizar la parte asignada de unidades de concurrenciareservadas.
  • En la T2, la función naranja y la función azul reciben constantemente más solicitudes. Al mismo tiempo, implementa otras funciones de AWS Lambda, que comienzan a recibir solicitudes. No asigna concurrencia reservada a estas otras funciones. Empiezan a utilizar las 200 unidades restantes de la concurrencia sin reservas.
  • En t3, la función naranja alcanza una concurrencia máxima de 400. Aunque hay competidores no utilizados en otras partes de su cuenta, la función naranja no puede acceder a ellos. La línea roja indica que la función naranja tiene limitaciones y es posible que AWS Lambda desestime las solicitudes.
  • En la t4, la función naranja comienza a recibir menos solicitudes y ya no está limitada. Sin embargo, sus otras funciones experimentan un pico de tráfico y comienzan a limitarse. Si bien hay concurrencia no utilizada en otras partes de sucuenta, esas otras funciones no pueden acceder a ella. La línea roja indica que sus otras funciones están experimentando limitaciones.
  • En t5, otras funciones comienzan a recibir menos solicitudes y ya no están limitadas.

En este ejemplo, observe que la reserva de concurrencia tiene los siguientes efectos:

  • Su función se puede escalar independientemente de otras funciones de su cuenta.   Todas sus cuentas funcionan en la misma región y no tienen concurrencia reservada y comparten el grupo de competidores sin reservas. Sin concurrencia reservada, otras funciones pueden utilizar potencialmente toda la concurrencia disponible. Esto evita que las funciones críticas se expandan si es necesario.
  • Su función no se puede escalar de forma descontrolada.   La concurrencia reservada pone un límite a la concurrencia máxima en supuesto. Esto significa que su función no puede utilizar la concurrencia reservada para otras funciones ni la concurrencia del grupo no reservado. Puedes reservar concurrencia para evitar que sufunción utilice toda la concurrencia disponible en sucuenta o sobrecargue los recursos intermedios.
  • Es posible que no puedas usar todas concurrencias disponibles en sucuenta.   La reserva de la concurrencia se calcula para el límite de concurrencia de sucuenta, pero esto también significa que otras funciones no pueden usar ese bloque de concurrenciareservado. Si supuesto no utiliza toda la concurrencia que le reservas, de hecho estás desperdiciando esa concurrencia. Eso no supone ningún problema, a menos que otras funciones de sucuenta puedan beneficiarse de una concurrencia desaprovechada.

Para gestionar la configuración de la concurrencia reservada para sus funciones, consulta Configurar la concurrencia reservada.

 

Concurrenciaaprovisionada

Utilice la concurrencia reservada para definir el número máximo de entornos de ejecución reservados para una función Lambda. Sin embargo, ninguno de estos entornos viene preinicializado. Como resultado, las llamadas a funciones pueden tardar más tiempo porque AWS Lambda debe inicializar primero el nuevo entorno antes de poder usarlo para invocar (invocar) su función. Cuando el inicio tarda más de lo esperado, esto se conoce como arranque en frío. Para mitigar los arranques en frío, puedes usar Provisioned Competition.

La concurrencia aprovisionada es la cantidad de entornos de ejecución preinicializados que desea asignar a su función. Si define la concurrencia aprovisionada en una función, AWS Lambda inicializa esa cantidad de entornos de ejecución para que estén preparados para responder inmediatamente a las solicitudes de funciones.

Al utilizar la concurrenciaaprovisionada, AWS Lambda sigue reciclando los entornos de ejecución en segundo plano. Sin embargo, en cualquier momento, AWS Lambda siempre garantiza que la cantidad de entornos pre-inicializados sea igual al valor de la configuración de concurrenciaaprovisionada de la función. Este comportamiento difiere del de la concurrencia reservada, ya que AWS Lambda puede cerrar completamente un entorno tras un período de inactividad. El siguiente diagrama ilustra esto comparando el ciclo de vida de un único entorno de ejecución al configurar la función mediante la concurrencia reservada en comparación con la concurrencia aprovisionada.

 

Para entender mejor la concurrencia aprovisionada, considere el siguiente diagrama:

 

En este diagrama, tienes un límite de concurrencia de cuenta de 1000. Decides dar 400 unidades de la concurrencia aprovisionada a la función naranja. Todas las funciones de sucuenta, incluida la función naranja, permiten utilizar las 600 unidades restantes de la concurrenciasin reserva.

El diagrama tiene 5 puntos de interés:

  • En t1, la función naranja comienza a recibir solicitudes. Como AWS Lambda pre-inicializó 400 instancias del entorno de ejecución, la función naranja está lista para ser invocada inmediatamente.
  • En t2, la función naranja alcanza las 400 solicitudes simultáneas. Como resultado, la función naranja no tiene concurrencia aprovisionada. Sin embargo, dado que todavía hay concurrencia sin reservas disponible, AWS Lambda puede utilizarla para gestionar solicitudes adicionales de la función naranja (no hay ninguna limitación). AWS Lambda debe crear nuevas instancias para cumplir con estas solicitudes y es posible que su función experimente latencias de inicio en frío.
  • En la t3, la función naranja devuelve 400 solicitudes simultáneas tras un breve aumento en el tráfico. Una vez más, AWS Lambda puede gestionar todas las solicitudes sin latencias de inicio en frío.
  • En el t4, las funciones de su cuenta experimentan una explosión de tráfico. Esta rafaga podría provenir de la función naranja o de cualquier otra función de sucuenta. AWS Lambda utiliza la concurrencia sin reservas para gestionar estas solicitudes.
  • En t5, las funciones de sucuenta alcanzan el límite máximo de 1000 puntos de concurrencia y los límites de experiencia.

El ejemplo anterior solo consideraba la concurrencia aprovisionada. En la práctica, puede definir tanto la concurrencia aprovisionada como la concurrencia reservada en un función. Podría hacerlo si tuviera  una función que gestionara una carga constante de invocaciones, pero que viera picos de tráfico de forma rutinaria durante los fines de semana. En este caso, puede utilizar la concurrencia aprovisionada para definir una cantidad básica de entornos para gestionar la solicitud durante la semana y utilizar la concurrencia reservada para gestionar los picos de los fines de semana. Considere el siguiente diagrama:

 

En este diagrama, supongamos que configura 200 unidades de concurrencia aprovisionada y 400 unidades de concurrencia reservada para la función naranja. Puesto que configuró la concurrencia reservada, la función naranja no puede utilizar ninguna de las 600 unidades de concurrencia sin reserva.

Este diagrama tiene 5 puntos de interés:

  • En t1, la función naranja comienza a recibir solicitudes. Como AWS Lambda pre-inicializó 200 instancias en tiempo de ejecución, la función naranja está lista para ser invocada inmediatamente.
  • En t2, la función naranja utiliza toda su concurrencia aprovisionada. Es posible que la función naranja siga atendiendo las solicitudes mediante la concurrencia reservada, pero esas solicitudes pueden sufrir latencias de inicio en frío.
  • En t3, la función naranja alcanza las 400 solicitudes simultáneas. Como resultado, la función naranja utiliza toda su concurrencia reservada. Como la función naranja no puede competir sin reservas, las solicitudes comienzan a ser limitadas.
  • En t4, la función naranja comienza a recibir menos solicitudes y ya no se acelera.
  • En t5, la función naranja se reduce a 200 solicitudes simultáneas, de modo que todas las solicitudes pueden volver a utilizar la concurrencia aprovisionada (es decir, sin latencias de inicio en frío).

Tanto la concurrencia reservada como la aprovisionada se cuentan para el límite de concurrencia de su cuenta y las cuotas regionales. En otras palabras, la asignación de concurrencias reservada y aprovisionada puede afectar a la reserva de concurrencia disponible para otras funciones. La configuración de la concurrencia aprovisionada conlleva cargos para su cuenta de AWS.

Para administrar la configuración de concurrencia aprovisionada para sus funciones, consulte Configurar la concurrencia aprovisionada. Para automatizar el escalado de concurrencia aprovisionado en función del horario o el uso de la aplicación, consulte Gestión de la concurrencia aprovisionada con el escalado automático de aplicaciones.

Como recomendación, preste atención al valor de las instancias reservadas y aprovisionadas para evitar costes innecesarios en su cuenta de AWS.

 

Comparación de la concurrencia reservada y la concurrencia aprovisionada

La siguiente es una tabla que resume y compara la concurrencia reservada y aprovisionada.

 

 

Cuotas de concurrencia

AWS Lambda define las cuotas para la cantidad total de concurrencia que puede utilizar en todas las funciones de una región. Estas cuotas existen en dos niveles:

  • A nivel de cuenta, sus funciones pueden tener hasta 1000 unidades simultáneas de forma predeterminada.  Para aumentar este límite, consulte Solicitar un aumento de cuota en la Guía del usuario de cuotas de servicio.
  • A nivel de función, puede reservar hasta 900 unidades de concurrenciapara todos sus funciones de forma predeterminada. Siempre se reservan 100 unidades de concurrencia para funciones que no reserven explícitamente la concurrencia. Por ejemplo, si aumentó el límite de concurrenciade la cuenta a 2000, puede reservar hasta 1900 unidades de concurrenciaa nivel de función.

 

Estime con precisión la concurrencia necesaria

Si su función se dedica actualmente al tráfico, puede ver fácilmente las métricas de su concurrencia mediante las métricas de CloudWatch. Recuerde que también puede calcular la concurrencia mediante la siguiente fórmula:

Concurrencia = (promedio de solicitudes por segundo) * (promedio de la duración de la solictud en segundos)

Puede estimar el número promedio de solicitudes por segundo con la métrica de invocación y la duración media de las solicitudes en segundos con la métrica de duración.

 

Métricas de la concurrencia

Puede utilizar las siguientes métricas para supervisar la concurrencia de sus funciones de Lambda.

 

Conclusiones

En general, el aprovisionamiento simultáneo y la limitación de las funciones de AWS Lambda se pueden gestionar mejor mediante el parámetro de concurrencia reservado. En los casos en que las aplicaciones empresariales se ejecuten en su cuenta de AWS y simplemente necesiten más de 1000 ejecuciones simultáneas (estándar), Amazon puede aumentar este límite solicitando límites más altos.

Si bien los límites de concurrencia son un buen indicador de la velocidad de transacciones por segundo (TPS) que puede ejecutar su servicio de negocio, este único factor no lo explica todo, ya que la duración media del tiempo de ejecución tiene un enorme efecto en la cantidad de solicitudes que un servicio puede procesar en un período de tiempo determinado. En otras palabras, una función de AWS Lambda que pueda ejecutarse en un proceso dos veces más rápido necesitará menos ejecuciones simultáneas para gestionar la misma cantidad de solicitudes, en comparación con una función más lenta. Optimice su código para que sea eficiente y eficiente y aumente el número de transacciones por segundo a las que podrá responder su solución.

 

 


Acerca del autor

Daniel Abib es arquitecto de soluciones empresariales en AWS y lleva más de 25 años trabajando en la gestión de proyectos, las arquitecturas de soluciones escalables, el desarrollo de sistemas y CI/CD, los microservicios, la arquitectura sin servidores y sin contenedores y la seguridad.  Trabaja apoyando a los clientes corporativos, ayudándolos en su viaje a la nube.  

https://www.linkedin.com/in/danielabib/

 

 

 

 

Revisor

Ana Barragán es Arquitecta de Soluciones en AWS, tiene más de 5 años de experiencia como Arquitecta de aplicación e integración, Arquitecturas de microservicio y sin servidor. Trabaja apoyando a los clientes en la modernización de sus aplicación apalancandose en los sercvicios de AWS.

Apoya activamente iniciativas de diversidad, inclusión y equidad.

https://www.linkedin.com/in/ana-milena-barragan-charry/