sqs node kinesis aws amazon-web-services aws-lambda amazon-kinesis

amazon web services - node - Amazon Kinesis & AWS Lambda Retries



sqs lambda node js (2)

Esta es una pregunta común sobre el procesamiento de eventos en Kinesis y trataré de darle algunos puntos para construir su función Lambda para manejar tales problemas con datos "dañados". Como es una práctica recomendada tener partes separadas de su sistema que escriben en el flujo de Kinesis y otras partes que leen del flujo de Kinesis, es común que tenga tales problemas.

Primero, ¿por qué tienes eventos tan problemáticos ?

El uso de Kinesis para procesar sus eventos es una buena manera de dividir un sistema complejo que realiza tanto el procesamiento de front-end (que sirve a los usuarios finales) como el procesamiento de back-end de código (análisis de eventos) al mismo tiempo, en dos partes independientes de su sistema. Las personas de front-end pueden centrarse en su negocio, mientras que las de back-end no necesitan impulsar los cambios de código en el front-end, si desean agregar funcionalidad para atender sus casos de uso analíticos. Kinesis es un búfer de eventos que rompe la necesidad de sincronización y simplifica el código de lógica de negocios.

Por lo tanto, nos gustaría que los eventos escritos en el flujo sean flexibles en su " esquema ", y si los equipos de front-end desean cambiar el formato del evento, agregar campos, eliminar campos, cambiar el protocolo o las claves de cifrado, deberían ser capaces de hacer eso tan a menudo como quieran.

Ahora depende de los equipos que están leyendo el flujo poder procesar tales eventos flexibles de una manera eficiente, y no interrumpir su procesamiento cada vez que ocurre un cambio. Por lo tanto, debería ser común que su función Lambda vea eventos que no puede procesar, y " píldora venenosa " no es un evento raro como podría esperarse.

Segundo, ¿cómo manejas estos eventos problemáticos?

Su función Lambda obtendrá un lote de eventos para procesar. Tenga en cuenta que no debe obtener los eventos uno por uno, sino en grandes cantidades de eventos. Si sus lotes son demasiado pequeños, rápidamente obtendrá grandes retrasos en el flujo.

Para cada lote, recorrerá los eventos, los procesará y luego verificará en DynamoDB el último ID de secuencia del lote. Lambda está realizando la mayoría de estos pasos automáticamente con (vea más aquí: http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-kinesis-events-adminuser-create-test-function.html ):

console.log(''Loading function''); exports.handler = function(event, context) { console.log(JSON.stringify(event, null, 2)); event.Records.forEach(function(record) { // Kinesis data is base64 encoded so decode here payload = new Buffer(record.kinesis.data, ''base64'').toString(''ascii''); console.log(''Decoded payload:'', payload); }); context.succeed(); };

Esto es lo que está sucediendo en el "camino feliz" , si todos los eventos se procesan sin ningún problema. Pero si encuentra algún problema en el lote y no " confirma " los eventos con la notificación de éxito, el lote fallará y obtendrá todos los eventos en el lote nuevamente.

Ahora debe decidir cuál es la razón del error en el procesamiento.

  • Problema temporal (regulación, problema de red ...): está bien esperar un segundo y volver a intentarlo un par de veces. En muchos casos el problema se resolverá solo.

  • Problema ocasional (sin memoria ...): es mejor aumentar la asignación de memoria de la función Lambda o disminuir el tamaño del lote. En muchos casos, tal modificación resolverá el problema.

  • Falla constante : significa que debe ignorar el evento problemático (ponerlo en una cola de mensajes no entregados (DLQ) o modificar su código para controlarlo.

El problema es identificar el tipo de falla en su código y manejarlo de manera diferente. Debe escribir su código Lambda de manera que lo identifique (tipo de excepción, por ejemplo) y reaccionar de manera diferente.

Puede utilizar la integración con CloudWatch para escribir tales fallas en la consola y crear las alarmas relevantes. También puede usar los registros de CloudWatch como una forma de registrar su "cola de mensajes no entregados" y ver cuál es la fuente del problema.

Soy muy nuevo en Amazon Kinesis, por lo que quizás esto sea solo un problema, pero en las Preguntas frecuentes de AWS Lambda dice:

Los registros de Amazon Kinesis y DynamoDB Streams que se envían a su función AWS Lambda están estrictamente serializados, por fragmento. Esto significa que si coloca dos registros en el mismo fragmento, Lambda garantiza que su función Lambda se invocará con éxito con el primer registro antes de que se invoque con el segundo registro. Si la invocación de un registro se agota, se limita o encuentra algún otro error, Lambda volverá a intentarlo hasta que tenga éxito (o el registro alcance su vencimiento de 24 horas) antes de pasar al siguiente registro. El orden de los registros en diferentes fragmentos no está garantizado, y el procesamiento de cada fragmento se realiza en paralelo.

Mi pregunta es, ¿qué sucede si, por alguna razón, un productor produce algún dato incorrecto y cuando la función Lambda lo detecta, se produce un error y luego vuelve a intentarlo constantemente? Esto significa que el error bloquearía el procesamiento de ese fragmento en particular durante 24 horas.

¿Es la mejor práctica manejar los errores de la aplicación de esta manera envolviendo el problema en un error personalizado y enviando este error hacia abajo junto con todos los registros procesados ​​con éxito y dejando que el consumidor lo maneje? Por supuesto, esto aún no ayudaría en el caso de un error irrecuperable que bloqueó el programa como un puntero nulo: nuevamente, volveremos al bucle de reintentos de bloqueo durante las próximas 24 horas.


No lo pienses demasiado, el Kinesis es solo una cola. Tiene que consumir un registro (es decir, salir de la cola) con éxito para continuar con el siguiente. Al igual que una pila FIFO.

El enfoque apropiado debe ser:

  • Obtener un registro de la corriente.
  • Procésalo en un bloque try-catch-finally.
  • Si el registro se procesa con éxito, no hay problema. <- TRY
  • Pero si falla, anótela a otro lugar para investigar la razón por la que falló. <- CAPTURA
  • Y al final de sus bloques lógicos, siempre persista la posición en DynamoDB. <- FINALMENTE
  • Si ocurre algo interno en su sistema (error de memoria, error de hardware, etc.) es otra historia; ya que puede afectar el procesamiento de todos los registros, no solo uno.

Por cierto, si el procesamiento de un registro lleva más de 1 minuto, es obvio que está haciendo algo mal. Como Kinesis está diseñado para manejar miles de registros por segundo, no debe darse el lujo de procesar trabajos tan largos para cada uno de ellos.

La pregunta que está haciendo es un problema general de los sistemas de colas, a veces llamado "mensaje venenoso". Tienes que manejarlos en tu lógica de negocio para estar seguro.

http://www.cogin.com/articles/SurvivingPoisonMessages.php#PoisonMessages