Escuché que quieres unirte a una gran fábrica. Primero, responda 11 preguntas sobre la serie de MQ que pone en peligro la vida.

Siguiendo la serie anterior de vida-muerte de mysql, descubrí que mi título se usaba mucho, qué vida-muerte guardián del zoológico, mucho multi-hilo de vida-muerte, esta vez, comencé la serie de preguntas de entrevistas, tema MQ, cola de mensajes como un medio de uso diario común La entrevista es también uno de los puntos que deben plantearse. Echemos un vistazo a las preguntas de la entrevista de MQ.

¿Por qué usa mq? ¿Cuál es el escenario de uso específico?

El papel de mq es muy simple, cortando picos y llenando valles. Tomando el escenario de realizar un pedido en una transacción de comercio electrónico, el proceso de una transacción a plazo puede implicar la creación de un pedido, la deducción de inventario, la deducción del presupuesto de actividad, la deducción de puntos, etc. Si el tiempo de cada interfaz es de 100 ms, entonces, en teoría, todo el enlace para realizar un pedido tardará 400 ms, lo que obviamente es demasiado tiempo.

Si todas estas operaciones se procesan sincrónicamente, en primer lugar, el enlace de llamada es demasiado largo para afectar el rendimiento de la interfaz y, en segundo lugar, el problema de las transacciones distribuidas es difícil de resolver. En este momento, los requisitos de coherencia en tiempo real, como la deducción presupuestaria y los puntos, no son tan elevados. Puede ser procesado de forma asíncrona por mq. Al mismo tiempo, considerando la inconsistencia causada por la asincronía, podemos usar el trabajo para reintentar para asegurar que la llamada de interfaz sea exitosa y, en general, las empresas tendrán una plataforma de verificación, como el problema del pedido exitoso, pero no se puede verificar la deducción de puntos a través de la verificación. Una solución al fondo.

Después de usar mq, nuestro enlace se ha vuelto más simple y, al mismo tiempo, la resistencia al estrés de todo nuestro sistema para enviar mensajes de forma asincrónica también ha aumentado.

¿Qué mq usas? ¿En base a qué tipo de selección?

Investigamos principalmente varios mqs, kafka, rabbitmq, rocketmq y activemq convencionales. La selección se basa principalmente en los siguientes puntos:

  1. Dado que la presión de qps de nuestro sistema es relativamente grande, el rendimiento es la consideración principal.

  2. Lenguaje de desarrollo, dado que nuestro lenguaje de desarrollo es Java, es principalmente para la conveniencia del desarrollo secundario.

  3. Es necesario para escenarios comerciales de alta concurrencia, por lo que es necesario admitir el diseño de arquitectura distribuida.

  4. Las funciones son completas, debido a los diferentes escenarios comerciales, se pueden utilizar mensajes secuenciales, mensajes de transacciones, etc.

Con base en las consideraciones anteriores, finalmente elegimos RocketMQ.


Kafka RocketMQ RabbitMQ ActiveMQ
Rendimiento de una sola máquina 100.000 nivel 100.000 nivel Diez mil Diez mil
Lenguaje de desarrollo Scala Java Erlang Java
Alta disponibilidad Arquitectura distribuida Arquitectura distribuida Arquitectura maestro-esclavo Arquitectura maestro-esclavo
actuación nivel ms nivel ms nosotros clase nivel ms
Caracteristicas Solo admite la función principal MQ Funciones completas como mensaje de secuencia y mensaje de transacción Fuerte concurrencia, buen rendimiento, baja latencia Productos comunitarios maduros, documentación rica

Mencionaste el envío asincrónico anteriormente, ¿cómo garantizar la confiabilidad del mensaje?

La pérdida de mensajes puede ocurrir en tres aspectos: el productor envía un mensaje, el MQ mismo pierde el mensaje y el consumidor pierde el mensaje.

Productor perdido

El posible punto para que el productor pierda el mensaje es que el programa no puede enviar y arroja una excepción sin reintentar el procesamiento, o el proceso de envío es exitoso pero el MQ flash de red no se recibe durante el proceso y el mensaje se pierde.

Dado que el envío síncrono generalmente no aparece de esta manera, no consideramos el problema del envío síncrono, nos basamos en el escenario de envío asíncrono.

El envío asíncrono se divide en dos métodos: asíncrono con devolución de llamada y asíncrono sin devolución de llamada , sin método de devolución de llamada. Después de que el productor lo envía, independientemente del resultado, el mensaje puede perderse. Usamos la forma de envío asincrónico + notificación de devolución de llamada + tabla de mensajes local. Se puede hacer una solución. Ejemplos de escenarios para los siguientes pedidos.

  1. Guarde los datos locales y la tabla de mensajes MQ después de realizar el pedido. En este momento, el estado del mensaje es de envío. Si la transacción local falla, el pedido falla y la transacción se revierte.

  2. Si el pedido es exitoso, regresará directamente al cliente con éxito y enviará el mensaje MQ de forma asincrónica

  3. Resultado del envío del mensaje de notificación de devolución de llamada MQ, correspondiente al estado de envío de actualización de la base de datos MQ

  4. El sondeo de TRABAJO excede un cierto tiempo (tiempo según la configuración comercial) y no ha enviado un mensaje exitoso para reintentar

  5. Configure la plataforma de monitoreo o el programa JOB para procesar mensajes fallidos, alarmas e intervención manual más de un cierto número de veces.

En términos generales, para la mayoría de los escenarios, la forma de devolución de llamada asincrónica es suficiente, y crearemos una solución completa solo para escenarios que necesitan estar completamente garantizados para no perder mensajes.

Falta MQ

Si el productor garantiza que el mensaje se envía al MQ, y el MQ todavía está en la memoria después de recibir el mensaje, la máquina está inactiva y no hay tiempo para sincronizar con el nodo esclavo, lo que puede hacer que el mensaje se pierda.

Por ejemplo, RocketMQ:

RocketMQ se divide en dos métodos: flasheo síncrono y flasheo asincrónico. El valor predeterminado es flasheo asincrónico, que puede hacer que el mensaje se pierda antes de flashear en el disco duro. Puede configurar el método de flasheo sincrónico para garantizar la confiabilidad del mensaje. De esta forma, incluso si MQ se cuelga, el mensaje se puede restaurar desde el disco cuando se restaura.

Por ejemplo, Kafka también se puede configurar:

acks=all 只有参与复制的所有节点全部收到消息,才返回生产者成功。这样的话除非所有的节点都挂了,消息才会丢失。
replication.factor=N,设置大于1的数,这会要求每个partion至少有2个副本
min.insync.replicas=N,设置大于1的数,这会要求leader至少感知到一个follower还保持着连接
retries=N,设置一个非常大的值,让生产者发送失败一直重试

Aunque podemos lograr el propósito de alta disponibilidad de MQ en sí a través de la configuración, todos tienen pérdidas de rendimiento. La forma de configurar debe sopesarse de acuerdo con el negocio.

Consumidor perdido

El escenario en el que el consumidor pierde el mensaje: el consumidor acaba de recibir el mensaje y el servidor está inactivo en este momento. MQ cree que el consumidor ya lo ha consumido y no enviará el mensaje repetidamente, y el mensaje se pierde.

De forma predeterminada, RocketMQ requiere que los consumidores respondan a la confirmación de confirmación, mientras que Kafka necesita habilitar manualmente la configuración y deshabilitar la compensación automática.

El consumidor no devuelve una confirmación de acuse de recibo. El mecanismo de retransmisión varía según los diferentes intervalos de tiempo de transmisión y tiempos del tipo MQ. Si el reintento supera el número de veces, entrará en la cola de mensajes no entregados y deberá procesarse manualmente. (Kafka no los tiene)

Hablaste del problema de las fallas de consumo de los consumidores ¿Qué pasa si las fallas de consumo han provocado una acumulación de mensajes?

Debido al problema de que los consumidores siempre cometen errores en el consumo, podemos considerarlo desde las siguientes perspectivas:

  1. El error del consumidor debe ser causado por un programa u otro problema. Si es fácil de solucionar, solucione el problema primero y deje que el consumidor reanude el consumo normal.

  2. Si el tiempo es demasiado tarde para tratarlo es problemático, realice el proceso de reenvío, escriba un plan de consumo temporal del consumidor, primero consuma el mensaje y luego reenvíelo a un nuevo tema y recurso MQ. El recurso de máquina de este nuevo tema se solicita por separado y debe poder llevarlo. Pila actual de noticias

  3. Después de procesar los datos de la acumulación, repare el consumidor para que consuma nuevos datos de MQ y MQ existentes, y restaure el estado original después de que se complete el nuevo consumo de MQ

¿Qué pasa si la acumulación de mensajes alcanza el límite de disco y los mensajes se eliminan?

Esta. . . ¿Qué diablos hay para borrarme? . . Cálmate, piensa de nuevo. . Si.

Inicialmente, el registro del mensaje que enviamos se guardó en la base de datos y los datos reenviados también se guardaron. Luego, podemos usar esta parte de los datos para encontrar la parte que falta de los datos y luego ejecutar un script separado para reenviarlos. Si el programa reenviado no está en la biblioteca, compárelo con el registro del consumidor, pero el proceso será un poco más difícil.

Habiendo dicho tanto, ¿puede hablar sobre el principio de implementación de RocketMQ?

RocketMQ consta de un grupo de registro de NameServer, un grupo de productores de productores, un grupo de consumidores de consumidores y varios agentes (procesos de RocketMQ). Su principio de arquitectura es el siguiente:

  1. Broker se registra con todos los NameServers cuando se inicia y mantiene conexiones largas, enviando un latido cada 30 segundos

  2. El productor obtiene la dirección del servidor Broker de NameServer al enviar un mensaje y selecciona un servidor para enviar el mensaje de acuerdo con el algoritmo de equilibrio de carga.

  3. Cuando Conusmer consume mensajes, también obtiene la dirección del Broker del NameServer y luego extrae activamente el mensaje para consumir

¿Por qué RocketMQ no usa Zookeeper como centro de registro?

Creo que hay varias razones para no usar zookeeper:

  1. Según la teoría de CAP, como máximo se pueden alcanzar dos puntos al mismo tiempo, mientras que el cuidador del zoológico satisface el CP, lo que significa que el cuidador del zoológico no garantiza la disponibilidad de los servicios. Cuando el cuidador del zoológico lleva a cabo elecciones, toda la elección lleva demasiado tiempo y todo el grupo está en Estado no disponible, que definitivamente es inaceptable para un registro. Como descubrimiento de servicio, debe diseñarse para estar disponible.

  2. Según consideraciones de rendimiento, la implementación de NameServer en sí es muy liviana y se puede escalar horizontalmente agregando máquinas para aumentar la resistencia al estrés del clúster. La escritura de zookeeper no es escalable y zookeeper solo puede resolver este problema dividiendo el campo. Para resolver el problema dividiendo múltiples grupos de cuidadores del zoológico, en primer lugar, la operación es demasiado complicada y, en segundo lugar, viola el diseño de A en CAP, lo que provoca la desconexión entre los servicios.

  3. El problema causado por el mecanismo de persistencia, el protocolo ZAB de ZooKeeper seguirá escribiendo un registro de transacciones en cada nodo de ZooKeeper para cada solicitud de escritura y, al mismo tiempo, agregará una instantánea regular de los datos de la memoria al disco para garantizar los datos. Para un escenario de descubrimiento de servicios simple, esto no es realmente necesario Este esquema de implementación es demasiado pesado. Y los datos almacenados por sí mismos deben estar altamente personalizados.

  4. La transmisión de mensajes debe depender débilmente del registro, y el concepto de diseño de RocketMQ se basa en esto. El productor obtiene la dirección del Broker del NameServer cuando envía el mensaje por primera vez y lo almacena en caché localmente. Si todo el cluster del NameServer no está disponible, en poco tiempo No tendrá mucho impacto en productores y consumidores.

¿Cómo guarda Broker los datos?

Los archivos de almacenamiento principales de RocketMQ incluyen archivos de registro de confirmación, archivos de cola de consumo y archivos de índice.

Después de que el broker reciba el mensaje, lo guardará en el archivo de commitlog y, al mismo tiempo, en el almacenamiento distribuido, cada broker guardará una parte de los datos del tema y, al mismo tiempo, se generará el archivo consumequeue bajo la messagequeue correspondiente a cada tema. Para guardar el desplazamiento de la ubicación física del registro de confirmación, la relación correspondiente entre la clave y el desplazamiento se guardará en el archivo de índice.

El archivo CommitLog se guarda en el directorio $ {Rocket_Home} / store / commitlog. En la figura, podemos ver claramente el desplazamiento del nombre del archivo. Cada archivo predeterminado es 1G, y se genera automáticamente un nuevo archivo cuando está lleno.

Dado que los mensajes del mismo tema no se almacenan continuamente en el registro de confirmación, es muy ineficiente para los consumidores obtener mensajes directamente del registro de confirmación, por lo que la dirección física del desplazamiento del mensaje en el registro de confirmación se guarda a través de la cola de consumo, de modo que el consumidor primero consume Ubique el archivo físico de commitlog específico de la cola de consumo de acuerdo con el desplazamiento, y luego ubíquelo rápidamente en el registro de compromiso de acuerdo con ciertas reglas (módulo de tamaño de archivo y desplazamiento).

¿Cómo sincronizar datos entre maestro y esclavo?

La sincronización de mensajes entre maestro y esclavo se realiza según el protocolo de la balsa:

  1. Una vez que el corredor recibe el mensaje, se marcará como no confirmado

  2. Entonces el mensaje se enviará a todos los esclavos.

  3. El esclavo devuelve una respuesta de confirmación al maestro después de recibir el mensaje.

  4. Después de recibir más de la mitad del acuse de recibo, el maestro marca el mensaje como comprometido

  5. Envíe un mensaje comprometido a todos los esclavos, y el esclavo también cambia el estado a comprometido

¿Sabes por qué RocketMQ es rápido?

Es debido al uso de almacenamiento secuencial, caché de página y flasheo asincrónico.

  1. Cuando escribimos el registro de confirmación, escribimos secuencialmente, por lo que el rendimiento será mucho mejor que la escritura aleatoria

  2. Al escribir el registro de confirmación, no se escribe directamente en el disco, sino que primero se escribe en el PageCache del sistema operativo

  3. Finalmente, el sistema operativo vacía de forma asincrónica los datos de la caché en el disco

¿Qué son los mensajes transaccionales y semitransaccionales? ¿Como paso?

Los mensajes de transacción son las capacidades de transacciones distribuidas similares a XA proporcionadas por MQ. La consistencia final de las transacciones distribuidas se puede lograr a través de mensajes de transacción.

Un mensaje semi-transaccional es un mensaje de que MQ ha recibido un mensaje del productor, pero no ha recibido una segunda confirmación y no se puede entregar.

El principio de realización es el siguiente:

  1. El productor primero envía un mensaje semi-transaccional a MQ

  2. MQ devuelve una confirmación después de recibir el mensaje

  3. El productor comienza a ejecutar asuntos locales

  4. Si la transacción se ejecuta correctamente, envíe la confirmación a MQ, si falla, envíe la reversión

  5. Si MQ no recibe el segundo compromiso de confirmación o retrotracción del productor durante mucho tiempo, MQ inicia una verificación de mensaje al productor.

  6. El productor consulta el estado final de la ejecución de la transacción.

  7. Envíe una segunda confirmación de acuerdo con el estado de la transacción de la consulta

Finalmente, si MQ recibe la segunda confirmación, puede entregar el mensaje al consumidor; de lo contrario, si es una reversión, el mensaje se guardará y eliminará después de 3 días.

<FIN>

Amigos a los que les gusta este artículo, bienvenidos a seguir al programador de cuentas oficial  Xiaohui y ver contenido más emocionante.

点个[在看],是对小灰最大的支持!

Supongo que te gusta

Origin blog.csdn.net/bjweimengshu/article/details/110412272
Recomendado
Clasificación