Hola, me llamo Vasily Bogonatov. Soy uno de los que pone mi mano y mi cabeza y pone mi alma al servicio de las colas de mensajes persistentes distribuidas de Yandex Message Queue. El servicio se hizo público a fines de mayo, pero dentro de Yandex se ha utilizado activamente en varios productos.
Hoy quiero contarles a los lectores de Habr sobre las colas de mensajes en general y sobre Yandex Message Queue en particular. Primero, quiero explicar qué es una "cola de mensajes persistentes distribuidos" y por qué es necesaria. Mostrar su valor práctico, la mecánica de trabajar con mensajes, hablar sobre la API y la usabilidad. En la segunda mitad del artículo, veremos el aspecto técnico: cómo se usa la base de datos Yandex en nuestras colas (esta es una base confiable de nuestro servicio), cómo se ve un enfoque ingenuo y mejorado para construir una arquitectura, qué problemas son causados por la distribución y cómo se pueden resolver.

¿Qué es una cola de mensajes persistentes distribuidos?
Wikipedia define la
cola de mensajes como "un componente de ingeniería de software utilizado para la interacción entre procesos o entre subprocesos dentro de un proceso". De hecho, este concepto es algo más amplio: los procesos que interactúan usando una cola pueden ubicarse en diferentes servidores e incluso en diferentes centros de datos.
Aclararemos un poco los términos.
Una cola de mensajes es un repositorio que proporciona la colocación y lectura de datos en un orden específico.
Dos tipos de entidades suelen interactuar con una cola:
- escritores (productores) : envían mensajes a la cola;
- lectores (consumidores) : reciben (leen) mensajes de la cola.
Al usar la cola, los lectores y escritores son independientes entre sí. Pueden trabajar con diferentes prestaciones, fiabilidad, disponibilidad e incluso pueden escribirse en diferentes lenguajes de programación.
El escenario principal para la cola: transmite mensajes de manera confiable y rápida del escritor al lector. A diferencia de la base de datos, la cola no está destinada al almacenamiento de mensajes a largo plazo. En muchas implementaciones populares, hay un parámetro correspondiente: "Período de retención de mensajes". Determina cuánto tiempo se almacena el mensaje hasta que se elimina permanentemente.
Descubrimos el concepto de cola, ir a la "distribución" y "persistencia".
- Distribución en nuestro caso significa la presencia de un clúster que almacena y procesa datos y metadatos en cola, combinando todos sus nodos en un solo conjunto utilizando una red informática.
- La persistencia implica que todos los mensajes en la cola se escriben en el disco, y el escritor recibe la confirmación de envío solo después de una grabación exitosa.
La distribución y la persistencia no afectan la funcionalidad principal de la cola, proporcionan tolerancia a fallas y confiabilidad del almacenamiento de datos. Qué tipos de fallas pueden ocurrir en nuestro sistema, lo consideraremos un poco más adelante. Sin embargo, no puedo negarme el placer y abrir un poco las tarjetas: en toda la historia de la existencia del servicio, no hemos perdido un solo mensaje guardado del cliente.
¿Para qué sirve la cola de mensajes?
La cola le permite separar las partes lógicamente independientes de los servicios entre sí, es decir, proporciona un
desacoplamiento , que es tan solicitado en los microservicios ahora populares. Esto aumenta la escalabilidad y la confiabilidad: siempre puede aumentar el flujo de grabaciones en la cola y agregar más lectores, manejadores de mensajes, mientras que la falla de los lectores no afecta el trabajo de los escritores.
Las colas suavizan las cargas máximas: actúan como amortiguadores para los lectores. Si las capacidades actuales del lector no son suficientes para el procesamiento instantáneo de todos los mensajes entrantes, los mensajes en cola se procesarán más tarde cuando la carga disminuya. El almacenamiento en búfer es útil para servicios con una carga inestable, donde no se necesitan eventos entrantes instantáneos.
Veamos cómo funciona, usando el ejemplo de un
robot de búsqueda (¡después de todo, Yandex comenzó con una búsqueda!), Que descarga, procesa y coloca páginas web en una base de datos. Tomemos tal arquitectura.
La cola de mensajes resuelve los siguientes problemas aquí:
- El robot funciona mucho más rápido que los trabajadores responsables de analizar y cargar páginas en la base de datos. Fuera de línea, los enlaces se acumularían y llenarían la memoria o el disco disponible. Lo mismo sucedería si los trabajadores no estuvieran disponibles temporalmente.
- Sin una cola, el robot necesita "conocer" la interfaz de trabajo de los trabajadores para poder asignarles tareas. La interfaz puede cambiar a medida que se desarrolla el producto.
- Un trabajador individual tiene una fiabilidad bastante baja, por lo que no hay garantía de que el enlace transmitido sea procesado por él por completo.
La cola proporciona almacenamiento de datos confiable con escala, le permite retrasar el procesamiento de los enlaces. Si un trabajador falla, el enlace sin procesar después de un cierto período de tiempo será devuelto a la cola para que otro trabajador lo procese. La cola tiene su propia interfaz, que se prueba y describe en la documentación, de modo que el robot de búsqueda y los sistemas de trabajo pueden desarrollar diferentes equipos en diferentes lenguajes de programación. Esto no afectará el rendimiento general.
Cómo funciona Yandex Message Queue con los mensajes
Aquí se pueden distinguir tres etapas principales:
- escribir un mensaje en la cola;
- leer un mensaje de la cola;
- Eliminar un mensaje de la cola.
Un registro se considera exitoso si el mensaje se ha almacenado de forma segura y pronto estará disponible para los lectores. La grabación de deduplicación es posible: cuando se ignora un intento repetido de grabar un mensaje enviado.
En el momento de la lectura, el mensaje está oculto de la cola por un período de tiempo llamado Visibilidad Timeout, y se vuelve inaccesible para otros lectores. Si el tiempo de espera de visibilidad expira, el mensaje vuelve a la cola y vuelve a estar disponible para su procesamiento. El orden en que se leen los mensajes está determinado por la cola, no por el lector.
El lector en sí y la conexión de red con él son potencialmente poco confiables. Es necesario un tiempo de espera de visibilidad para poder devolver un mensaje a la cola cuando el lector falla o la conexión se desconecta. De lo contrario, es probable que un solo mensaje nunca se procese correctamente.
Después de una lectura exitosa, el mensaje se transmite al cliente con el identificador ReceiptHandle. Un identificador indica datos específicos que deben eliminarse de la cola de mensajes.
Tipos de cola en Yandex Message Queue
El primer tipo y el más utilizado es la cola estándar. Se caracteriza por un alto rendimiento (miles de mensajes por segundo), excelente rendimiento y corto tiempo de ejecución de operaciones básicas. Las colas estándar consisten en fragmentos lógicos y admiten una escala de ancho de banda casi lineal.
Las colas estándar no admiten la deduplicación de mensajes al escribir en una cola y no garantizan el orden de lectura. Debido al uso de fragmentos, una solicitud de lectura puede no devolver un solo mensaje, incluso si están en la cola. La mayoría de las veces esto sucede en el modo de
sondeo corto , cuando la lectura proviene de un fragmento seleccionado al azar.
El segundo tipo,
FIFO , es el opuesto de la cola estándar. Proporciona un estricto orden de lectura, admite deduplicación al escribir e intentos repetidos de leer mensajes. El rendimiento y la escalabilidad son inferiores a los estándares. El rendimiento de la cola FIFO está limitado a 30 solicitudes por segundo. Se recomienda utilizar FIFO cuando necesite intentar garantizar la semántica de entrega "exactamente una vez". Por lo general, la palabra "cola" significa FIFO.
API Yandex Message Queue
API es un componente extremadamente importante de cualquier producto. Una buena interfaz de software debe ser simple y directa, requiriendo una mínima familiarización con la documentación para un uso efectivo. No debe permitir realizar acciones extrañas o innecesarias y protegerse contra errores estúpidos, informando oportunamente la violación del "contrato".
Si el sistema tiene una API de este tipo, rápidamente recibe usuarios leales y está rodeado de "envoltorios" convenientes para diferentes plataformas y lenguajes de programación.
La API de Amazon Simple Queue Service (AWS SQS API) es un ejemplo de dicha interfaz, probada por el tiempo y una gran cantidad de clientes. Por lo tanto, decidimos no inventar una interfaz única para Yandex Message Queue, pero implementamos el soporte para la API de AWS SQS, y con mucho cuidado.
En la mayoría de los casos, es suficiente que el usuario de SQS cambie el punto final (dirección de servicio), la región (en este momento solo usamos "ru-central1") y obtenga nuevas credenciales dentro de Yandex.Cloud. Todo lo demás, por ejemplo, un script que usa la
línea de comandos de AWS , el código que usa AWS SDK o un servicio listo en
Celery o
boto , es muy probable que no se toque. La lógica y la funcionalidad del servicio de cola seguirán siendo las mismas.
Una descripción detallada de los métodos de la API Yandex Message Queue se encuentra en la
documentación del servicio .
Un poco sobre conveniencia
Yandex Message Queue es un servicio administrado, es decir, Yandex. Cloud es responsable del funcionamiento de los servidores y el software. El equipo de servicio monitorea el estado de las colas, reemplaza rápidamente los discos fallidos, elimina las interrupciones de la red y lanza actualizaciones. La actualización no detiene el servicio: mientras instalamos la nueva versión de YMQ en un grupo de servidores, el equilibrador de carga redirige cuidadosamente el tráfico a otros. Para que los usuarios no noten nada.
Para que le resulte más conveniente controlar el funcionamiento de las colas, hemos agregado una gran cantidad de gráficos visuales a YMQ, aquí solo se muestra una pequeña parte de ellos. Los gráficos se encuentran en la consola Yandex.Cloud, en la sección "Estadísticas".
Le diremos sobre los cuatro gráficos más útiles en nuestra opinión:
- El gráfico "Mensajes en cola" lo ayuda a monitorear la acumulación de datos en la cola. Un crecimiento en el gráfico puede significar que los manejadores no están administrando la carga o que el procesamiento se ha detenido.
- Gráfico "Antigüedad del mensaje más antiguo en la cola" : los valores grandes indican problemas con el procesamiento del mensaje. Si todo funciona correctamente, los mensajes no deberían estar en la cola por mucho tiempo.
- El gráfico "Número de intentos de leer un mensaje" muestra cuándo los mensajes comienzan a leerse varias veces. Esto puede significar que los controladores se bloquean cuando reciben algunos mensajes.
- El gráfico "Tiempo de espera " indica cuánto tiempo transcurre desde el momento en que se envía el mensaje a la cola hasta que el controlador lo recibe.
Los gráficos ayudan a evaluar instantáneamente la dinámica de la cola y la presencia de fallas sin la necesidad de ver registros.
Discutimos puntos más o menos generales, ahora pasemos a los detalles.
Cómo Yandex Database Queue usa Yandex Database
El servicio Yandex Message Queue se basa en la base de
datos Yandex Database (YDB) tolerante a fallas geo-distribuida, que proporciona una consistencia estricta y soporte para transacciones ACID. Ahora no desensamblaremos su dispositivo y características, nos limitaremos al esquema general.
Una cola en YMQ consta de fragmentos lógicos, representados por un conjunto fijo de tablas YDB. Cada tabla almacena su propia información. Por ejemplo, hay una tabla de estado general llamada State, que almacena offs y el número real de mensajes. Hay una tabla con datos y metadatos de mensajes. Hay una tabla con atributos relacionados.
Todas las operaciones principales con la cola (trabajar con mensajes, cambiar atributos, crear y eliminar) funcionan con la jerarquía de tablas y directorios YDB, o consultas transaccionales a una o más tablas de la cola. Los datos dentro de las tablas de la cola son la fuente de la verdad absoluta. Por lo tanto, además del funcionamiento correcto y estable de la base de datos, es necesario garantizar un almacenamiento confiable y una alta disponibilidad de datos.
Nuestra información se almacena en varias réplicas: una copia en cada uno de los tres centros de datos de Yandex. Si uno de los centros de datos no está disponible, el número de réplicas en los restantes se duplica. Por lo tanto, se restablece el nivel de fiabilidad requerido. Incluso si falla un centro de datos completo y una mesa de servicio en otra, los datos serán completamente accesibles.
La primera versión de la arquitectura Yandex Message Queue
La primera versión de la arquitectura YMQ, que nosotros mismos llamamos ingenua, se veía así.
El diagrama muestra la ruta de la solicitud HTTPS desde el cliente YMQ al repositorio YDB. Veamos los componentes principales:
- El equilibrador L3 envía una solicitud al centro de datos Yandex más cercano al usuario. Esto reduce la latencia de la red, aunque la carga se distribuye de manera desigual.
- Nginx en la máquina virtual Yandex.Cloud termina las conexiones HTTPS, brinda protección contra ataques a la red y envía la solicitud al servidor YMQ, que ya está en HTTP.
- El servidor HTTP YMQ implementa la lógica API SQS HTTP, valida y traduce la solicitud a un formato protobuf fuertemente tipado.
- Sistema de actor YMQ - Sistema de actor . Simultáneamente lanzó miles de actores diferentes que intercambian información. El sistema de actores de cada host forma parte de un clúster. Todos los actores del grupo viven y actúan como un todo. La lógica de negocios de YMQ se implementa en varios actores involucrados en las solicitudes de transacciones a YDB.
- Tabletas YDB ("tabletas"): parte del núcleo YDB, que es responsable de trabajar con tablas en consultas y transacciones. Las tabletas en sí no almacenan datos. Estas son estructuras de control en la memoria que pueden restaurar el estado en caso de una falla de hardware.
- El almacenamiento es un almacenamiento confiable, distribuido y tolerante a fallas.
Esta arquitectura tiene un inconveniente: todos los servidores en el clúster trabajan independientemente con tablas de la misma cola. Esto afecta negativamente el rendimiento y evita la organización de cachés confiables de mensajes ocultos y legibles. Es difícil limitar el flujo de solicitudes, y esto es muy importante para cualquier servicio altamente cargado.
Arquitectura de Yandex Message Queue con maestros de cola
La activación de carga mostró que la primera versión de la arquitectura soporta alrededor de 450 mensajes por segundo por cola con un fragmento. Era muy pequeño.
El principal problema eran las consultas de contención. Una gran cantidad de transacciones lógicamente conflictivas rápidamente llevaron a los cachés de mensajes ocultos a un estado inconsistente. Para resolver el problema, presentamos una entidad especial: el maestro de colas.
Un maestro de cola es un actor que, en condiciones normales, existe en un clúster en una sola instancia y pasa todas las solicitudes asociadas con una cola particular. Si una solicitud a la cola llega a un servidor donde falta el maestro deseado, un actor proxy especial redirige la solicitud y luego traduce la respuesta recibida del maestro.
Cuando se utiliza el Asistente de cola, la memoria caché correcta de los mensajes desbloqueados reduce la contención al trabajar con tablas. La implementación de la restricción del flujo de solicitudes se simplifica, por ejemplo, a través del
depósito Leaky . Se encuentran disponibles métricas de cola rápidas y precisas: número de mensajes, tráfico total y similares. Puede agrupar solicitudes similares.
En teoría, dicha arquitectura tiene ciertas desventajas asociadas con la centralización:
- Reducción de la tolerancia a fallas: si falla una máquina virtual con un maestro, todas las colas con maestros no estarán disponibles. Sin embargo, los mecanismos especiales de YDB le permiten crear nuevos maestros dentro del clúster en solo unos segundos. Esto resuelve en gran medida el problema.
- Escalabilidad limitada: todas las solicitudes pasan por un host. La desventaja son las tabletas YDB niveladas. Hacen todo el trabajo duro con los datos. Y el maestro envía asincrónicamente solicitudes y procesa los resultados recibidos. Esto lo convierte en una entidad "ligera" que no crea un efecto de "cuello de botella" durante las pruebas de estrés.
Asistente de consultas en cola
Las transacciones distribuidas con tablas de base de datos conducen a ciertos costos adicionales, por lo que la idea de reducir el número de consultas nos pareció lógica. Cien transacciones para grabar mensajes de una en una es mejor convertirlas en una transacción para grabar cien mensajes a la vez. Con los maestros de colas, implementar dicho procesamiento por lotes (lote) es mucho más fácil.
El procesamiento por lotes aumenta ligeramente la latencia durante las operaciones. En cambio, el ancho de banda aumenta significativamente. Con el procesamiento por lotes, una cola de un solo fragmento puede procesar hasta 30,000 solicitudes por segundo.
En general, la carga de la cola puede ser muy diferente: miles de mensajes por segundo y varios mensajes por día. Necesitábamos optimizar el trabajo con colas usando un algoritmo flexible. . YMQ , . .
:
- , .
- , .
- , . .
TCP/IP. : , latency . , . .
Yandex Message Queue, , . , , -.
YDB . YMQ .
, , , .
YMQ . . «» .
YDB . , , , «». , . .
: . , «» . -, «» , «», .
« » . , , .
Yandex Message Queue
Yandex Message Queue – - . . , . .
- - , , . .
- API , . , .
- , : , . , . . boto, 24/7, - .
- , , . .
. - . . .
:
.
En conclusión
La tarea de los equipos de infraestructura en Yandex es crear y mantener soluciones confiables, escalables y productivas, en base a las cuales se puedan lanzar nuevos productos de manera rápida y exitosa que mejoren la vida de los usuarios finales. Dentro de la empresa, nuestro servicio de colas ha demostrado su utilidad y se ha convertido en parte de la arquitectura de Yandex.Video, Yandex.Market, Yandex.Education, Yandex.Taxi y otros servicios.Ahora está disponible en el ecosistema Yandex.Cloud y se puede usar para crear servicios dentro y fuera de la propia nube. Ahora los nuevos usuarios en el registro reciben una subvención de dinero para familiarizarse, por lo que puede probar Yandex Message Queue de forma gratuita.