Uso de AWS Lambda funciones en Amazon Neptune - Amazon Neptune

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Uso de AWS Lambda funciones en Amazon Neptune

AWS Lambda las funciones tienen muchos usos en las aplicaciones de Amazon Neptune. Aquí ofrecemos una guía general para usar las funciones de Lambda con cualquiera de los controladores y variantes de lenguaje populares de Gremlin, así como ejemplos específicos de funciones de Lambda escritas en Java y Python. JavaScript

nota

La mejor forma de utilizar las funciones de Lambda con Neptune ha cambiado con las versiones recientes del motor. Neptune solía dejar abiertas las conexiones inactivas mucho después de reciclar un contexto de ejecución de Lambda, lo que podía provocar una pérdida de recursos en el servidor. Para mitigar esta problema, solíamos recomendar abrir y cerrar una conexión con cada invocación a Lambda. Sin embargo, a partir de la versión 1.0.3.0 del motor, se ha reducido el tiempo de espera de las conexiones inactivas para que dejen de tener pérdidas tras reciclar un contexto de ejecución de Lambda inactivo, por lo que ahora recomendamos utilizar una sola conexión durante el contexto de ejecución. Esto debería incluir un poco de gestión de errores y código back-off-and-retry repetitivo para gestionar el cierre inesperado de las conexiones.

Administrar las conexiones de WebSocket Gremlin en las funciones AWS Lambda

Si utiliza una variante del lenguaje Gremlin para consultar Neptune, el controlador se conecta a la base de datos mediante una conexión. WebSocket WebSockets están diseñados para soportar escenarios de conexión cliente-servidor de larga duración. AWS Lambda, por otro lado, está diseñado para apoyar ejecuciones relativamente efímeras y apátridas. Esta discordancia en la filosofía de diseño puede provocar algunos problemas inesperados al utilizar Lambda para consultar Neptune.

Una AWS Lambda función se ejecuta en un contexto de ejecución que la aísla de otras funciones. El contexto de ejecución se crea la primera vez que se invoca la función y se puede volver a utilizar para invocaciones posteriores de la misma función.

Sin embargo, nunca se utiliza un contexto de ejecución para gestionar varias invocaciones simultáneas de la función. Si varios clientes invocan la función de forma simultánea, Lambda genera un contexto de ejecución adicional para cada instancia de la función. Todos estos nuevos contextos de ejecución pueden, a su vez, volver a utilizarse en invocaciones posteriores de la función.

En algún momento, Lambda recicla los contextos de ejecución, especialmente si han estado inactivos durante algún tiempo. AWS Lambda expone el ciclo de vida del contexto de ejecución, incluidas las Init Shutdown fases Invoke y, mediante extensiones Lambda. Con estas extensiones, puede escribir código que limpie los recursos externos, como las conexiones a bases de datos, cuando se recicle el contexto de ejecución.

Una práctica recomendada habitual es abrir la conexión a la base de datos fuera de la función de controlador de Lambda para que se pueda volver a utilizar con cada llamada al controlador. Si la conexión a la base de datos se interrumpe en algún momento, puede volver a conectarse desde el interior del controlador. Sin embargo, existe el peligro de que se produzcan pérdidas de conexión con este enfoque. Si una conexión inactiva permanece abierta durante mucho tiempo después de que se destruya un contexto de ejecución, las situaciones de invocación de Lambda intermitentes o en ráfagas pueden perder conexiones gradualmente y agotar los recursos de la base de datos.

Los límites y los tiempos de espera de conexión de Neptune han cambiado con las versiones más recientes del motor. Anteriormente, cada instancia admitía hasta 60 000 WebSocket conexiones. Ahora, el número máximo de WebSocket conexiones simultáneas por instancia de Neptune varía según el tipo de instancia.

Además, a partir de la versión 1.0.3.0 del motor, Neptune redujo el tiempo de inactividad de las conexiones de una hora a aproximadamente 20 minutos. Si un cliente no cierra una conexión, la conexión se cierra automáticamente tras un tiempo de inactividad de 20 a 25 minutos. AWS Lambda no documenta la duración del contexto de ejecución, pero los experimentos muestran que el nuevo tiempo de espera de la conexión de Neptune se alinea bien con los tiempos de espera inactivos del contexto de ejecución de Lambda. Cuando se recicla un contexto de ejecución inactivo, es muy probable que Neptune ya haya cerrado su conexión o que se cierre poco después.

Recomendaciones para su uso AWS Lambda con Amazon Neptune Gremlin

Ahora recomendamos utilizar un único origen de recorrido de gráficos y conexión durante toda la vida útil de un contexto de ejecución de Lambda, en lugar de utilizar uno para cada invocación de función (cada invocación de función gestiona solo una solicitud de cliente). Dado que las solicitudes de clientes simultáneas las gestionan distintas instancias de funciones que se ejecutan en contextos de ejecución distintos, no es necesario mantener un grupo de conexiones para gestionar estas solicitudes dentro de una instancia de función. Si el controlador de Gremlin que utiliza tiene un grupo de conexiones, configúrelo para que utilice solo una conexión.

Para gestionar los errores de conexión, utilice la lógica de reintento en cada consulta. Aunque el objetivo sea mantener una conexión única durante todo el tiempo que dure un contexto de ejecución, los eventos de red inesperados pueden provocar que la conexión se interrumpa de forma abrupta. Estos errores de conexión se manifiestan como errores diferentes en función del controlador que se utilice. Debe codificar la función de Lambda para gestionar estos problemas de conexión e intentar volver a conectarse si es necesario.

Algunos controladores de Gremlin gestionan automáticamente las reconexiones. El controlador de Java, por ejemplo, intenta restablecer automáticamente la conectividad con Neptune en nombre del código del cliente. Con este controlador, el código de función solo necesita retroceder y volver a intentar la consulta. Los controladores JavaScript y Python, por el contrario, no implementan ninguna lógica de reconexión automática, por lo que con estos controladores, el código de la función debe intentar volver a conectarse después de retroceder y solo volver a intentar la consulta una vez que se haya restablecido la conexión.

Los ejemplos de código que se indican a continuación incluyen la lógica de reconexión en lugar de suponer que el cliente se está encargando de ello.

Recomendaciones para utilizar las solicitudes de escritura de Gremlin en Lambda

Si la función Lambda modifica los datos del gráfico, considere la posibilidad de adoptar una back-off-and-retry estrategia para gestionar las siguientes excepciones:

  • ConcurrentModificationException: la semántica de las transacciones de Neptune significa que, en ocasiones, se produce un error en las solicitudes de escritura con una ConcurrentModificationException. En estas situaciones, pruebe un mecanismo de reintento exponencial back-off-based .

  • ReadOnlyViolationException: dado que la topología del clúster puede cambiar en cualquier momento como resultado de eventos planificados o imprevistos, las responsabilidades de escritura pueden migrar de una instancia del clúster a otra. Si el código de función intenta enviar una solicitud de escritura a una instancia que ya no es la instancia principal (escritor), se produce un error en la solicitud con una ReadOnlyViolationException. Cuando esto suceda, cierre la conexión existente, vuelva a conectarse al punto de conexión del clúster y, a continuación, vuelva a intentar la solicitud.

Además, si utilizas una back-off-and-retry estrategia para gestionar los problemas de las solicitudes de escritura, considera la posibilidad de implementar consultas idempotentes para las solicitudes de creación y actualización (por ejemplo, utilizando fold () .coalesce () .unfold ().

Recomendaciones para utilizar las solicitudes de lectura de Gremlin en Lambda

Si tiene una o varias réplicas de lectura en el clúster, es buena idea equilibrar las solicitudes de lectura entre estas réplicas. Una opción es utilizar el punto de conexión del lector. El punto de conexión del lector equilibra las conexiones entre las réplicas, incluso si la topología del clúster cambia al añadir o eliminar réplicas, o al promover una réplica para que se convierta en la nueva instancia principal.

Sin embargo, el uso del punto de conexión del lector puede provocar un uso irregular de los recursos del clúster en algunas circunstancias. El punto final del lector funciona cambiando periódicamente el host al que apunta la entrada. DNS Si un cliente abre muchas conexiones antes de que cambie la DNS entrada, todas las solicitudes de conexión se envían a una sola instancia de Neptune. Este puede ser el caso de un caso de Lambda de alto rendimiento en el que un gran número de solicitudes simultáneas a la función de Lambda provoca la creación de varios contextos de ejecución, cada uno con su propia conexión. Si todas estas conexiones se crean casi simultáneamente, es probable que todas apunten a la misma réplica del clúster y que sigan apuntando a esa réplica hasta que se reciclen los contextos de ejecución.

Una forma de distribuir las solicitudes entre las instancias es configurar la función de Lambda para que se conecte a un punto de conexión de la instancia, elegido al azar en una lista de puntos de conexión de la instancia de réplica, en lugar del punto de conexión del lector. El inconveniente de este enfoque es que requiere que el código de Lambda gestione los cambios en la topología del clúster mediante la supervisión del clúster y la actualización de la lista de puntos de conexión cada vez que cambia la pertenencia al clúster.

Si está escribiendo una función de Lambda de Java que necesita equilibrar las solicitudes de lectura entre las instancias del clúster, puede utilizar el cliente Gremlin para Amazon Neptune, un cliente Java Gremlin que conoce la topología del clúster y que distribuye de forma equitativa las conexiones y solicitudes entre un conjunto de instancias de un clúster de Neptune. Esta publicación de blog incluye un ejemplo de función de Lambda de Java que usa el cliente Gremlin para Amazon Neptune.

Factores que pueden ralentizar los arranques en frío de las funciones de Lambda en Neptune Gremlin

La primera vez que se invoca una AWS Lambda función se denomina arranque en frío. Existen varios factores que pueden aumentar la latencia de un arranque en frío:

  • Asegúrese de asignar memoria suficiente a la función de Lambda.   — La compilación durante un arranque en frío puede ser considerablemente más lenta para una función Lambda de lo que sería si estuviera activa, EC2 ya que AWS Lambda asigna los CPU ciclos de forma lineal en proporción a la memoria que se asigna a la función. Con 1.769 MB de memoria, una función recibe el equivalente a un v completo CPU (un v segundo de créditos por CPU segundo). El impacto de no asignar suficiente memoria para recibir los CPU ciclos adecuados es particularmente pronunciado en el caso de las funciones Lambda de gran tamaño escritas en Java.

  • Tenga en cuenta que habilitar la autenticación de IAM bases de datos puede ralentizar un arranque en frío; AWS Identity and Access Management (IAM) la autenticación de bases de datos también puede ralentizar los inicios en frío, especialmente si la función Lambda tiene que generar una nueva clave de firma. Esta latencia solo afecta al arranque en frío y no a las solicitudes posteriores, ya que una vez que la autenticación de IAM base de datos ha establecido las credenciales de conexión, Neptune solo valida periódicamente que siguen siendo válidas.