Video Summary and Transcription
En esta charla, se cubren las características clave de las funciones de AWS Lambda, incluyendo la arquitectura del servicio, la composición y la optimización del código Node.js. Se explican los dos modelos operativos de Lambda, la invocación asíncrona y síncrona, destacando la escalabilidad y disponibilidad del servicio. Se discuten las características de las funciones Lambda, como los reintento y el mapeo de la fuente del evento, junto con el ciclo de vida del micro VM y las tres etapas de una función Lambda. Se explican las técnicas de optimización de código, incluyendo la reducción del tamaño del paquete y el uso de opciones de caché, y se recomiendan herramientas como webpack y Lambda Power Tuning para la optimización. En general, Lambda es un servicio potente para manejar la escalabilidad y los picos de tráfico mientras permite a los desarrolladores centrarse en la lógica empresarial.
1. Introducción a AWS Lambda
En esta sesión, cubriremos las características clave de las funciones Lambda, cómo funciona la arquitectura del servicio, cómo componer una función Lambda en AWS y cómo optimizar su código Node.js para Lambda. Una función Lambda le permite concentrarse en crear valor para sus clientes escribiendo código que mapea sus capacidades empresariales en producción. Solo paga por el tiempo de ejecución, lo que lo hace rentable tanto para entornos de producción como de prueba. Puede proporcionar su código a través de un archivo zip o imágenes de contenedor, y elegir entre una gama de lenguajes incorporados o traer el suyo propio. Un cliente incluso creó un tiempo de ejecución personalizado en COBOL.
Hola a todos y bienvenidos a esta sesión sobre AWS Lambda Bajo el Capó. Sé que varios de ustedes no solo están buscando cómo construir algo de código, sino también por qué deberían construir el código de cierta manera. Ya sea que seas un experto en escribir funciones Lambda o estés pensando en usar serverless y AWS Lambda en tu próxima carga de trabajo, creo que al final de esta charla podrás tomar una decisión consciente sobre por qué escribir el código de cierta manera.
Entonces, sin más preámbulos, vamos a empezar. Mi nombre es Luca. Soy un especialista principal en serverless en AWS. Estoy basado en Londres. Soy un orador internacional y autor de libros. Entonces, en esta charla vamos a cubrir bastante terreno, y especialmente lo que quiero cubrir es, en primer lugar, ¿qué es una función Lambda? Porque tal vez tengas una idea de lo que es, pero intentemos clavar las características clave de las funciones Lambda. Luego avanzamos, entendiendo cómo funciona la arquitectura del servicio por debajo del capó. Luego discutimos cómo componemos una función Lambda en AWS. Y luego nos movemos a los ciclos de vida de la función y cómo aprovecharlos para maximizar el beneficio de su código. Y por último, pero no menos importante, estamos hablando de cómo optimizar su código Node.js para Lambda.
Hay mucho terreno que cubrir, así que comencemos. ¿Qué es una función Lambda? Una función Lambda, en resumen, es tan simple como proporcionas algo de código y nosotros nos encargamos de la provisión y gestión del servicio para ti. Así que no tienes que pensar en el lado de la red o cómo orquestar la escalabilidad y así sucesivamente. Solo te enfocas en lo que realmente importa para ti. Así que creando valor para tus clientes y además escribiendo algo de código Node.js que básicamente mapea tus capacidades empresariales en producción. Pagas por milisegundo. Así que cada vez que invocas un Lambda, pagas solo por el tiempo de ejecución y nada más. Y eso es una excelente manera de pensar no solo en producción, sino también en, por ejemplo, pruebas un entorno de staging que no se usa 24-7, como tu entorno de producción. Allí, solo pagas por lo que usas. No tienes que aprovisionar contenedores o máquinas virtuales que están allí 24-7. Puedes servir el contenido de dos maneras. Puedes proporcionarnos tu código a través de un archivo zip cuando el archivo es de hasta 250 megabytes, o si es más grande que eso, puedes usar imágenes de contenedor de hasta 10 gigabytes. En ambos casos, puedes aprovechar los beneficios de AWS Lambda sin ningún problema. También ofrecemos lenguajes incorporados. Tenemos algunos tiempos de ejecución que están disponibles y son administrados por nosotros para ti, como Java, Go, Node.js, .NET, Python, y muchos otros. Pero también, si tienes un caso de uso específico, puedes traer el tuyo, y lo operacionalizamos de la misma manera exacta. Un ejemplo clásico, tuvimos un cliente que trabajaba en finanzas, y necesitaban usar COBOL, pero realmente se enamoraron de Lambda, así que crearon su propio tiempo de ejecución personalizado en COBOL.
2. Modos de Invocación y Arquitectura de Lambda
Por último, pero no menos importante, escala en milisegundos. Lambda tiene dos modelos operativos: invocación asíncrona e invocación sincrónica. El código que escribes se ejecuta dentro de un sandbox MicroVM, que es parte de un Worker que opera en una zona de disponibilidad. AWS se encarga de hacer que tu código sea altamente disponible en varios centros de datos. En modo sincrónico, la puerta de enlace API llama a un servicio frontend en AWS Lambda, que inmediatamente invoca a un worker para ejecutar tu código y devolver la respuesta. En el caso de las funciones Lambda síncronas, los eventos se introducen en una cola de mensajes y el llamador recibe un reconocimiento.
Por último, pero no menos importante, scale en milisegundos. Así que, basándonos en tu patrón de tráfico, nos encargamos de scaling tu función Lambda y de responder a todas las solicitudes que llegan. Así que, normalmente, desde la perspectiva de un desarrollador, lo que ves es que estás escribiendo algo de code, como puedes ver en la izquierda de esta diapositiva, y luego lo subes a tu cuenta de AWS, y ocurre algo de magia, y empiezas a tener una API que funciona.
La realidad es que hay mucho más. Así que la pregunta ahora es, ¿alguna vez has pensado cómo funciona Lambda bajo el capó? Así que echemos un vistazo a eso. En primer lugar, hay dos modelos operativos de las funciones Lambda. El primero es la invocación asíncrona, donde, por ejemplo, tienes una puerta de enlace API que expone tu API, llega una solicitud de un cliente, y se dispara una función Lambda con la respuesta, y luego sirves la respuesta de manera sincrónica a tu cliente. La otra opción es la invocación asíncrona, donde en este caso tienes un servicio que está empujando un evento al servicio Lambda, el servicio Lambda almacena el evento en una cola interna de eventos, y luego la función Lambda empieza a recuperar estos eventos de manera lenta pero constante y a trabajar en ellos. El solicitante, en este caso Amazon EventBridge, por ejemplo, recibe directamente un reconocimiento y nada más. Y esas son las dos formas en que funciona la invocación de Lambda.
Así que, si vemos en el gran esquema de las cosas, cómo desde lo que ves en la izquierda de la diapositiva, ya sea que haya varios servicios o incluso si son sincrónicos o no, están enviando una solicitud al servicio AWS Lambda, que es el gran rectángulo que está dentro de esta diapositiva. Y cómo moverse hacia tu code que está en el extremo derecho de esta diapositiva, donde hay un sandbox MicroVM, es un viaje interesante. Y especialmente, quiero destacar primero lo que está pasando dentro de tu sandbox. El sandbox es donde se ejecuta tu code. Ahora, si piensas en eso, tu MicroVM, donde está el code que has escrito y es operacionalizado por nosotros, se ejecuta dentro de un Worker. Y obviamente, no hay solo un Worker. Hay muchos más. Normalmente en AWS, tenemos varias zonas de disponibilidad. Y como puedes ver aquí, tienes varios Workers ejecutándose dentro de una zona de disponibilidad. Y la zona de disponibilidad es un centro de data. Así que piensa en cómo se ve un centro de data, y esa es tu zona de disponibilidad. Pero normalmente en AWS, cada vez que creamos una región, está compuesta por varias zonas de disponibilidad. Por lo tanto, cada vez que estás empujando el code dentro de Lambda, automáticamente, vas a tener tu code que está disponible en varios centros de data. No tienes que hacer nada. Solo te enfocas en qué región quieres desplegar y cuál es la lógica de negocio. Y nosotros nos encargamos de no solo operacionalizar el code, sino también de hacerlo altamente disponible en toda nuestra infraestructura. Así que ahora vamos a profundizar en el modo de invocación y cómo funciona dentro de la architecture. Así que en el modo sincrónico, lo que pasa es, por ejemplo, en la puerta de enlace API está llamando de manera sincrónica, a un servicio frontend que está dentro del servicio AWS Lambda que está devolviendo una respuesta inmediata porque lo que pasa es que está invocando a un worker específico, poniendo en marcha un micro VM y tu code empieza a ejecutarse y devuelve inmediatamente la respuesta o el error al cliente. En cambio, cuando estás pensando en el modo de invocación para las funciones Lambda síncronas, es ligeramente diferente. Así que en este caso, por ejemplo, tenemos SNS que está empujando un evento en un mensaje en el frontend que el frontend está almacenando dentro de una cola interna el mensaje específico el llamador recibe un reconocimiento simplemente diciendo sí, hemos tenido en cuenta tu solicitud y luego entras dentro de la cola interna.
3. Características de la Función Lambda y Ciclo de Vida del Micro VM
La belleza de Lambda es que admite características como reintentos, definición de destino y mapeo de fuentes de eventos. Con el mapeo de fuentes de eventos, puedes manejar fácilmente el procesamiento por lotes y el manejo de errores sin escribir lógica adicional. Cuando subes código, tu micro VM se crea usando File Cracker, un micro VM de código abierto diseñado para funciones Lambda. Funciona cargando el código, creando el micro VM y eliminando los inicios en frío. Una vez que se crea el micro VM, tu función Lambda se ejecuta sin problemas sin latencia. El ciclo de vida de una función Lambda implica tres etapas.
Y la belleza de este enfoque es que no solo estamos ejecutando tu code, sino que también estamos apoyando un montón de características como puedes configurar el mecanismo de reintentos. Hasta tres invocaciones en total. Cuando algo falla puedes definir el destino, y también puedes definir esa cola posterior que es un patrón útil cuando quieres reintentar automáticamente la creación de tu propio flujo de trabajo, los errores, o incluso hacer la debugging de tu sistema.
Hay un tercer método del que no hemos hablado, es el mapeo de fuentes de eventos y hay ciertos servicios como MSK o Kinesis o SQS o Dynamo streams que están utilizando otro servicio que está disponible en los servicios AWS Lambda llamado mapeo de fuentes de eventos. El mapeo de fuentes de eventos se encarga de extraer mensajes de la fuente y luego invoca sincrónicamente tu función Lambda. Obviamente, gracias al mapeo de fuentes de eventos puedes hacer procesamiento por lotes, manejo de errores y mucho más. Lo hermoso de esto es que pensamos en otros servicios, necesitas escribir tu propia lógica. En este caso para Lambda está completamente obstruido para ti, así que solo configuras cómo se ve tu lote de mensajes y luego eso será enviado a tu code de función Lambda para operacionalizar tu lógica de negocio.
Ahora, hemos visto cómo funciona el servicio, pero ahora intentemos entender cuando subes algo de code cómo se ve cuando tu micro VM ha sido preparado para ejecutar el code. Así que cada micro VM está usando File Cracker. File Cracker es una fuente abierta, digamos micro VM que creamos para la función Lambda, especialmente para la computación serverless, y ahora también está disponible para otros servicios AWS. Es completamente de código abierto, como mencioné antes. Por lo tanto, puedes verlo. Puedes ver cómo funciona, pero este es un fantástico software que estamos utilizando para operacionalizar tu code para funciones Lambda.
Entonces, ¿cómo funciona? Así que normalmente funciona de esta manera. Cuando hay una entrada, alguien está activando e invocando una función Lambda, seleccionamos un host de trabajo, la entrada del evento llega al host de trabajo. Lo primero que hace es cargar el code que has subido. Esto se llama normalmente inicio en frío y significa que es inicio en frío principalmente porque lleva un poco más de tiempo de lo habitual recuperar el code en tiempo de ejecución. Y luego creando tu micro VM con Frye, cracker y obviamente el tiempo de ejecución que seleccionaste o el contenedor. Hay diferentes niveles en cómo estas cosas se almacenan en caché dentro del sistema. Pero en general, la idea es que tienes un inicio en frío cuando construyes por primera vez el micro VM con el code y todo. Después de eso tienes tu función Lambda caliente. Así que empiezas a golpear la función Lambda del micro VM varias veces con diferentes entradas, y de repente ya no tienes inicio en frío. Tienes muchas respuestas que no están manejando. No tiene ninguna latencia en generar mi micro VM. Y eso es genial. Así que ahora creo que es un buen momento para pensar en la parte del ciclo de vida o cómo funciona la función Lambda cuando generas un nuevo micro VM. Este es probablemente el mejor diagrama que puedo mostrarte, y está totalmente disponible en nuestro sitio web. Normalmente, cuando tienes una función Lambda, pasas por tres etapas.
4. Inicialización, Invocación y Apagado de Lambda
Tienes las fases de inicialización, invocación y apagado en las funciones Lambda. Durante la inicialización, se cargan las extensiones y los tiempos de ejecución, y se realizan tareas específicas de la función como la recuperación de secretos y el establecimiento de conexiones de base de datos. En la fase de invocación, el entorno de ejecución está caliente, lo que permite una respuesta rápida a las solicitudes. Finalmente, durante el apagado, se apagan el tiempo de ejecución y las extensiones. Para obtener más información, consulta la documentación.
Tienes la inicialización, luego la invocación que ocurre varias veces hasta que tu entorno de ejecución sigue en funcionamiento y disponible, y luego el apagado, que es cuando, digamos, tu función Lambda ya no se llama más. Por lo tanto, como dijimos, pagas por tu tiempo de ejecución. Después de un tiempo, reclamamos la infraestructura, y simplemente sigues hasta la próxima invocación, obviamente. Ahora, en cada uno de esos pasos, tienes diferentes cosas que están sucediendo. Entonces, comencemos a ver la fase de inicialización. Entonces, en la fase de inicio, tenemos, en este caso, la extensión porque puedes usar la extensión para tu función Lambda. Piensa en los sidecars que están disponibles en tus entornos de ejecución, y eso suele ser lo primero que cargas. Luego, está la carga del tiempo de ejecución. Entonces, si, por ejemplo, seleccionaste node.js, se inicializa el tiempo de ejecución de node, y luego, de repente, tienes la inicialización de la función. Aquí es una de las partes clave del sistema. Normalmente, en la inicialización de la función, lo que haces es, por ejemplo, recuperar secretos que se utilizan durante la invocación de tu función lambda, o incluso parámetros que se almacenan externamente de tu función lambda. Lo hermoso de esto es que se hace solo en la fase de inicialización, por lo que no necesitas recuperar cada vez cierta información. Incluso establecer una conexión con una database, puedes hacerlo en la fase de inicialización y luego olvidarte de eso. Eso estará disponible para todas las invocaciones que el entorno de ejecución está haciendo. Entonces, podemos pasar al entorno de ejecución, lo siento, la fase de invocación, donde el entorno de ejecución ya está caliente y, por lo tanto, empiezas a responder a cada solicitud. Ten en cuenta que hasta que el entorno de ejecución esté en funcionamiento, puedes omitir definitivamente toda la fase de inicialización. Por lo tanto, tu función lambda será bastante rápida, porque simplemente está invocando y está allí, disponible para ti. Al final, cuando reclamamos la función lambda, tienes un tiempo de ejecución de apagado y el apagado de las extensiones. Bastante fácil. Si quieres saber más, puedes consultar la documentation en este enlace y podrás ver
5. Optimización del Código en Funciones Lambda
Para optimizar tu código en Lambda, es crucial reducir el tamaño del paquete. Herramientas como webpack y ESBL pueden ayudar a eliminar dependencias y funciones innecesarias, lo que resulta en tiempos de inicio de código más rápidos. La concurrencia provisionada es útil para cargas de trabajo predecibles, permitiéndote mantener las funciones Lambda calientes durante los períodos de tráfico pico. La nueva versión 3 del SDK de JavaScript AES ofrece un tamaño de paquete más pequeño y manejo de conexión TCP incorporado. Las opciones de almacenamiento en caché de Lambda incluyen almacenamiento en caché en memoria en el entorno de ejecución y el uso de servicios como Elastic File System o Elastic Cache para el almacenamiento de datos en múltiples funciones. La herramienta de código abierto Lambda Power Tuning ayuda a optimizar el tiempo de invocación y el costo al determinar la mejor configuración, incluyendo la arquitectura y el tamaño de la memoria. Lambda Power Tools simplifica la observabilidad con la integración de registros, seguimiento y métricas. Lambda es un servicio poderoso que te permite enfocarte en la lógica de negocio mientras maneja la escalabilidad y los picos de tráfico. Para obtener más información, consulta las charlas adicionales y el documento técnico de seguridad.
más información sobre este diagrama y cómo funciona el ciclo de vida. Ahora, hablemos de cómo puedes optimizar tu code en la función lambda, y especialmente en el code de Node.js. Como dijimos aquí, tenemos nuestra entrada que se recibe externamente del servicio, luego generas un microvm con tu code. Pero obviamente, para reducir el tiempo de inicio del code, una de las técnicas clave es intentar reducir el tamaño de tu paquete. Y en este caso, ¿cómo funciona? Puedes usar webpack, ESBL, cualesquiera que sean las herramientas que se necesiten para reducir el tamaño de tu paquete. Esto obviamente hará un inicio de code más rápido porque de repente tu code es solo una pieza de lógica y un montón de bibliotecas que estás utilizando. Pero todas las dependencias de desarrollo, por ejemplo, y todas las, digamos, funciones que no están usando ese code que puedes eliminar, el tree shaking que puedes aplicar, es totalmente útil para reducir el inicio del code cuando estás trabajando con funciones Lambda. Otra funcionalidad que está disponible en Lambda, si tienes un específico carga de trabajo, por ejemplo, imagina que tienes una carga de trabajo que es predecible y sabes de antemano que el domingo por la noche de 7pm a 9pm, vas a tener un aumento de tráfico, puedes usar concurrencia provisionada. La concurrencia provisionada básicamente te permitirá establecer un marco de tiempo y seleccionar una función Lambda específica para mantenerla caliente. Entonces lo que sucede es que seleccionamos tu función Lambda y empezamos a inicializarla de antemano para ese período de tiempo específico en el que vas a tener algunas funciones Lambda que están disponibles y ya están calientes para satisfacer el aumento de tráfico. Esa es una forma fantástica de escalar tus cargas de trabajo sin tener un inicio en frío y además si tienes un nivel superior esperando la fase de inicialización se va a encargar de esa parte y por lo tanto lo que va a suceder es que cosas como por ejemplo recuperar parámetros de fuentes externas como el sistema o la tienda de parámetros del sistema manager estará disponible en la fase de inicialización y luego no lo necesitarás más, así que reduces el tiempo de ejecución de tu función lambda. Otra sugerencia es usar javascript AES SDK versión 3. Esa es una versión bastante nueva, obviamente el paquete es más pequeño en comparación con la v2 y eso es algo genial. También hay un montón de otras características que son bastante útiles, así que para antes estabas usando la versión 2 del SDK y DynamoDB una sugerencia que usualmente proporcionamos es que necesitas mantener viva la conexión TCP de lo contrario cada vez que llamas y ejecutas la función lambda establece una nueva conexión TCP. Ahora estas están desapareciendo con la versión 3 y están incorporadas dentro del SDK por lo que ya no tienes que manejarlo por ti mismo además eso es algo que a menudo la gente no sabe es que los tiempos de ejecución de node.js incorporan una versión específica del SDK de AWS por lo tanto si no estás usando una versión específica del SDK o estás usando digamos ya la implementación simplificada o algo similar no necesitas incorporar dentro de tu dependencia el SDK pero puedes aprovechar el que se envía junto con el tiempo de ejecución por lo que tienes una dependencia menos que manejar.
El almacenamiento en caché para lambda puedes almacenar en memoria y hay dos formas de hacerlo. El almacenamiento en caché en memoria podría ocurrir en el entorno de ejecución, así como hemos enviado dentro de tu micro VM y eso está ocurriendo en la fase de inicialización como hemos visto antes y la charla extensivamente. También tienes una carpeta temporal que puede almacenar hasta 10 gigabytes de data por defecto es 512 megabytes pero obviamente puedes aumentar este límite. También puedes almacenar y almacenar en caché en múltiples funciones lambda si es necesario. Por ejemplo, puedes usar servicios como el sistema de archivos elásticos o elástico cache utilizando Redis o memcache en el caso de elastic cache para almacenar tus data en múltiples funciones lambda. Así que en ese caso van a recuperarlos de EFS o elastic cache y estarás listo para ir. Otra herramienta que vale la pena mencionar y una optimization a un alto ratio de enlace es usar una herramienta de open-source llamada lambda power tuning. Power tuning ejecuta tu code y función lambda de una manera que te permite entender cuál es la mejor configuración para tu tiempo de invocación de la función lambda y el costo de invocación. Obviamente hay diferentes parámetros que puedes establecer y muy a menudo la gente piensa que la menor cantidad de memoria siempre será la más barata pero en realidad no es así y por eso tenemos esta herramienta que puedes ejecutarla y entender cuál es la correcta architecture para ejecutar lambda podría ser arm o x86 y también cuál es el tamaño de memoria correcto basado en la optimization que quieres. Como puedes ver en esta diapositiva puedes optimizar para el costo puedes optimizar para el tiempo y ambas son una dimensión válida para pensar. Por último, pero no menos importante, hay una biblioteca llamada lambda power tools que simplifica la integración de observability dentro de tu lambda. De hecho, los registros, el seguimiento y las métricas se convierten en una brisa gracias al uso de lambda power tools y te permitirá tener las best practices incorporadas dentro de tu code fuera de la caja. Si quieres saber más puedes encontrar el enlace en esta diapositiva. Para resumir lo que hemos visto hasta ahora es que lambda es un servicio fantástico que te permite usar solo lo que realmente necesitas. Optimizas tu enfoque, tu día a día en la creación de lógica de negocio más que en operacionalizar tu infraestructura y definitivamente terminar esos picos de tráfico hasta cierto punto y también otros tipos de cargas de trabajo. Si quieres saber más sobre cómo funciona lambda bajo el capó hay otra charla que realmente recomiendo que fue hecha por un colega mío Julian Wood y con también un Ingeniero Principal del Equipo Lambda que va a hablar más in depth de lo que hemos visto hasta ahora y también puedes echar un vistazo al documento técnico de security que está disponible en el sitio web de AWS que proporciona mucha información sobre el modelo de security y cómo funciona lambda bajo el capó. ¡Espero que hayas disfrutado de esta sesión y disfrutes del resto de la conferencia!
Comments