En esta publicación, obtendrás conocimientos prácticos sobre cómo funciona SQS FIFO desde una perspectiva detallada. Aprenderás a lograr el mayor rendimiento posible y a configurarlo correctamente con ejemplos de código TypeScript de CDK.
Introducción del autor invitado
Marcos Henrique es ingeniero sénior de la nube (también conocido como AWS Janitor) en Welbe Care y desarrollador de la comunidad de AWS sin servidor. Con más de diez años de experiencia en tecnología, le apasionan las tecnologías de la nube y las aprovecha para resolver problemas complejos y mejorar la escalabilidad y la eficiencia del sistema.
Puedes seguir a Marcos en su página de LinkedIn .
Tabla de contenido
Breve introducción de SQS
Amazon SQS (Simple Queue Service) no es "simple" en términos de cómo se pueden desacoplar los componentes de una aplicación en la nube o cómo se puede escalar. SQS ofrece un sistema de colas distribuidas seguro, altamente disponible y confiable para el almacenamiento y procesamiento asincrónico de mensajes. Proporciona ciclos de vida de mensajes configurables y entrega garantizada a través de almacenamiento redundante en múltiples zonas de disponibilidad.
Si bien SQS ofrece muchas características beneficiosas, genera algunos desafíos debido a dos limitaciones inherentes:
Sin orden garantizado : los mensajes pueden llegar fuera de orden, lo que requiere que los desarrolladores gestionen el orden.
Posibles duplicados : los mensajes podrían enviarse más de una vez, lo que requiere un manejo de idempotencia .
Para superar esas limitaciones, podemos utilizar otra variante de SQS: el SQS FIFO (primero en entrar, primero en salir) .
Sistema de clasificación FIFO
Las colas FIFO (First-In-First-Out) tienen todas las capacidades de las colas estándar. Están diseñadas para mejorar la comunicación entre aplicaciones cuando el orden de las operaciones y los eventos es crítico o cuando no se pueden tolerar duplicados.
FIFO permite gestionar los mensajes como en tu línea de cafetería favorita, respetando el orden de los mensajes y eliminando la duplicación de mensajes.
Como todo lo demás, no es una función complementaria y tiene limitaciones/cuotas , como ser más lenta y más costosa que las colas SQS normales.
Enviar y recibir mensajes
Al trabajar con colas FIFO de SQS, es fundamental comprender el ID de deduplicación de mensajes y el ID de grupo de mensajes. El ID de deduplicación de mensajes es un token que evita que SQS envíe el mismo mensaje varias veces. Si se envía correctamente un mensaje con un ID de deduplicación en particular, se aceptan otros mensajes con el mismo ID, pero no se vuelven a enviar en un plazo de 5 minutos. Así es como SQS FIFO elimina la limitación de mensajes duplicados.
El ID de grupo de mensajes etiqueta un mensaje que pertenece a un grupo específico. Los mensajes del mismo grupo se procesan de a uno por vez en orden, pero los mensajes de diferentes grupos pueden procesarse fuera de orden. Así es como SQS FIFO elimina la limitación de mensajes fuera de orden.
Como se muestra en la imagen a continuación, si envía muchos mensajes con identificadores únicos a una cola FIFO, Amazon SQS los pondrá en fila y los procesará en orden. Los mensajes con el mismo identificador de grupo se almacenan y procesan a medida que llegan. Para mantener todo ordenado, cada remitente debe usar un identificador de grupo único. Solo recuerde que, si no etiqueta sus mensajes con un identificador de grupo, Amazon SQS no lo ayudará.
Tenga en cuenta que no puede solicitar mensajes directamente con un ID de grupo específico en el extremo del receptor del mensaje.
Cuando extraes mensajes de una cola FIFO con varios ID de grupo, Amazon SQS intenta darte tantos mensajes como puedas del mismo grupo para que otros consumidores puedan obtener mensajes de diferentes grupos. Una vez que recibes un mensaje de un grupo, solo llegan más mensajes de ese grupo.
Puedes recibir muchos mensajes a la vez, manteniendo su orden FIFO, pero si no hay suficientes de un grupo, recibirás algunos de otro, como se ve en la imagen a continuación, donde el Consumidor 1 recibe mensajes de los grupos A y B en el segundo lote. Los lotes tienen un tamaño máximo de 10 mensajes.
Limitaciones
Antes de comenzar, es importante tener en cuenta que no existe una solución milagrosa, por lo que debemos abordar dos limitaciones antes de implementar.
Actuación
La primera limitación es el rendimiento. La compatibilidad con la entrega de mensajes exactamente una vez y en orden puede afectar significativamente el rendimiento de la cola FIFO, lo que podría crear un cuello de botella en su aplicación. Las colas FIFO tienen un rendimiento menor que las colas estándar, con un límite predeterminado de 300 transacciones por segundo (TPS). Sin embargo, el procesamiento por lotes puede aumentar este límite a 3000 TPS.
Siempre debe tener en cuenta las limitaciones de rendimiento para manejarlas de manera eficaz. Por ejemplo, cree el ID del grupo de mensajes con cuidado, ya que los mensajes con el mismo ID de grupo de mensajes se devolverán en orden. Si bien este es el comportamiento previsto para una cola FIFO, recuerde que solo una vez que se haya eliminado un mensaje de la cola se devolverá el siguiente mensaje con el mismo ID de grupo de mensajes.
Desduplicación de mensajes
La segunda limitación es la deduplicación de mensajes. La deduplicación basada en contenido es posible con colas FIFO, que eliminan los mensajes duplicados en un plazo de 5 minutos. Este período de tiempo no se puede modificar, por lo que las aplicaciones que dependen de la deduplicación de mensajes deben tener en cuenta esta restricción.
Escenario real de alto rendimiento
Estábamos implementando un sistema de mensajería para informar a nuestros clientes sobre los resultados de las pruebas de laboratorio, por lo que necesitábamos que estos mensajes siguieran una cronología específica. Imagínate recibir una serie de mensajes sin contexto cronológico; sería un caos. Por lo tanto, SQS no era ideal para nuestro caso, por lo que optamos por FIFO. Sin embargo, no todo fue un camino de rosas.
Dado que tenemos miles de clientes y miles de mensajes para cada cliente, necesitábamos algo rápido. Dadas las limitaciones de rendimiento mencionadas anteriormente, tuvimos que repensar toda nuestra configuración. Como FIFO puede causar un cuello de botella , tuvimos que encontrar una manera de hacerlo escalable. Ahí es donde entra en juego el alto rendimiento para las colas FIFO en Amazon SQS .
FIFO SQS de alto rendimiento al rescate
En primer lugar, esto nos salvó el día y nos ayudó con nuestro gran volumen de mensajes. Como no existe una solución milagrosa, siempre debemos ser conscientes de las limitaciones de nuestras herramientas.
Las colas FIFO de alto rendimiento en Amazon SQS manejan muchos mensajes y mantienen un orden estricto, lo que resulta perfecto para el procesamiento de pedidos de alta demanda. Sin embargo, solo son necesarias si el orden de los mensajes es crucial o el volumen de mensajes es bajo. Las colas estándar son más simples y económicas para mensajes de pequeña escala o poco frecuentes.
Para obtener detalles sobre las cuotas de mensajes y las estrategias de distribución de datos, consulte Cuotas de servicio de Amazon SQS .
Particiones y distribución de datos
Amazon SQS almacena datos de cola FIFO en particiones , que se replican automáticamente en varias zonas de disponibilidad dentro de una región de AWS. No es necesario que administre estas particiones, Amazon SQS lo hace por usted.
Para las colas FIFO, Amazon SQS ajusta la cantidad de particiones según la demanda:
Si la tasa de solicitud es alta, se agregan más particiones a la cuota regional.
Si la utilización es baja, se pueden reducir las particiones.
Esta gestión se realiza en segundo plano, manteniendo siempre disponibles tu cola y tus mensajes.
Al agregar un mensaje a una cola FIFO, Amazon SQS utiliza el ID del grupo de mensajes con una función hash para determinar qué partición almacena el mensaje. Los mensajes se almacenan en el orden en que llegan y su ubicación se basa en el valor hash del ID del grupo de mensajes.
Aumentar la cantidad de grupos de mensajes aumentará potencialmente la cantidad de particiones y el rendimiento en colas FIFO SQS de alto rendimiento.
Ejemplo de codificación
Configuremos nuestra cola FIFO SQS con alto rendimiento habilitado usando CDK y Typescript.
Primero, configuraremos nuestra cola y luego escribiremos el código para el productor de mensajes:
Línea 10: Debemos proporcionar el sufijo ".fifo"; de lo contrario, fallará durante la implementación.
Línea 11: Este parámetro debe ser verdadero para configurar nuestro fifo.
Línea 12 : aquí, configurará su alto rendimiento y especificará si la deduplicación de mensajes se produce en el grupo de mensajes o en el nivel de cola. Por ejemplo, si necesita tener múltiples deduplicaciones basadas en cada grupo de mensajes, aquí es donde ocurre la magia. De lo contrario, puede encontrar algunos problemas, ya que el valor predeterminado está configurado para toda la cola.
Línea 13: especifica si la cuota de rendimiento de la cola FIFO se aplica a toda la cola o a cada grupo de mensajes. Establezca esta opción como PER_MESSAGE_GROUP_ID, la configuración necesaria para utilizar un alto rendimiento para las colas FIFO
Línea 14 : Esto se estableció como falso porque en este ejemplo no estamos usando un contenido de mensaje bien definido; sin embargo, si es su caso, puede establecerlo como verdadero.
Ahora, vamos a producir mensajes:
Línea 11 : esta línea configura los atributos del mensaje (título y tipo) para metadatos específicos asociados con el contenido del mensaje.
Línea 21 : especifica un MessageDeduplicationId único para garantizar que los mensajes duplicados se identifiquen y procesen correctamente en la cola FIFO.
Línea 22 : define un MessageGroupId para agrupar los mensajes relacionados (resultados de análisis de sangre) que deben permanecer en orden durante el procesamiento.
Consejos y trucos
Ahora que entendemos los conceptos básicos, exploremos algunos consejos y trucos para escribir código FIFO SQS que maneje un alto rendimiento.
Generación y deduplicación de mensajes
Repasemos algunas consideraciones antes de enviar un mensaje a una cola FIFO SQS de alto rendimiento.
Para configurar la deduplicación, puede habilitar la deduplicación basada en contenido, que utiliza un hash SHA-256 del cuerpo del mensaje. Este método puede ser complicado y es posible que no funcione como se espera si hay una diferencia mínima, como un espacio adicional, en el mensaje.
Como alternativa, puedes proporcionar tú mismo un ID de deduplicación de mensajes. Esto resulta especialmente útil si trabajas con un proveedor de chat de mensajes como WhatsApp, donde enviar distintos mensajes a la misma persona suele requerir un ID único para cada ID de grupo de mensajes.
En el primer caso de uso, si su aplicación envía cuerpos de mensajes idénticos y proporciona una ID de deduplicación única para cada mensaje, debe elegir con cuidado .
Por otro lado, si su aplicación envía cuerpos de mensajes únicos, habilite la deduplicación basada en contenido .
Por último, no se necesitan cambios para los consumidores, pero si el procesamiento toma mucho tiempo, agregue un ID de intento de solicitud de recepción a cada acción ReceiveMessage para manejar reintentos y evitar pausas en la cola debido a intentos fallidos.
Prefiera las API por lotes
Como FIFO es más lento que el SQS normal, debemos considerar lotes al recibir mensajes.
El tamaño máximo de lote para las colas FIFO es de 10 registros . El procesamiento con este límite mejora significativamente el rendimiento, casi 10 veces mejor que configurar la cola FIFO de SQS en batchSize: 1 .
Reducir costos
El comportamiento predeterminado de SQS FIFO es eliminar la duplicación de mensajes en toda la cola.
Si desea deduplicar mensajes dentro de cada ID de grupo de mensajes, debe habilitar el modo de alto rendimiento, lo que puede resultar costoso. Para ahorrar costos, puede lograr un resultado similar agregando un prefijo al ID de deduplicación de mensajes al enviar mensajes según el ID de grupo de mensajes. Recuerde que cada grupo debe tratarse como una partición, por lo que es esencial considerar sus cuotas en consecuencia.
Echemos un vistazo al ejemplo de código a continuación:
En las líneas 17 y 18 , puedes ver dónde se establece el cambio. Esto nos permite lograr la deduplicación por ID de grupo de mensajes sin incurrir en costos adicionales. Por ejemplo, supongamos que tienes diferentes ID de grupo de mensajes para varios tipos de comunicaciones, como WhatsApp, correos electrónicos y SMS.
Al asignar un ID de grupo de mensajes único a cada tipo de comunicación, se garantiza que los mensajes dentro del mismo grupo se procesen en orden y sin duplicaciones. Este enfoque ayuda a organizar los mensajes de forma lógica y eficiente, evitando duplicados dentro de cada grupo y manteniendo la secuencia de entrega de mensajes sin necesidad de mecanismos de deduplicación adicionales, que de otro modo podrían generar costos adicionales.
Fallos y reintentos
Para gestionar los mensajes fallidos y reintentados, es importante asegurarse de que se vuelvan a intentar sin preocuparse por el orden o la creación de mensajes nuevos. Si un mensaje no se puede enviar, el productor debe volver a enviarlo utilizando el mismo ID de deduplicación.
Una vez que reciba un mensaje con un ID de grupo, solo recibirá más mensajes de ese grupo una vez que lo haya gestionado, o volverá a ser visible. Para obtener una comprensión integral de los reintentos y los fallos, incluidos los conceptos de colas de mensajes fallidos, consulte estas guías detalladas:
Consejos generales de SQS
Por último, te recomiendo que consultes el artículo sobre mejores prácticas de SQS de AWS.
Conclusión
Como todo en la vida, debemos analizar nuestro caso, pensar en las mejores prácticas y ser escépticos de que las cosas funcionen la primera vez; siempre debemos considerar el peor escenario al diseñar una solución.
Debemos ser siempre frugales porque esto es una cualidad, no un defecto del caso de desarrollo. Necesitamos tener una mente alineada con la necesidad de escala hoy en día. Todo es escalable, y todo se puede consumir masivamente, por lo que necesitamos que nuestros sistemas tengan cada vez más flexibilidad pero sin descuidar la resiliencia y seguridad de nuestras aplicaciones; por esto, decidí condensar todo lo que he aprendido a través del trabajo duro estudiando montones de artículos y documentación, este post fue creado con mucho sudor y lágrimas.
¡Feliz cola y que tus mensajes lleguen siempre a tiempo (y en orden)!
Comments