[Kafka de la serie cuatro de la entrada al abandono] Estrategia de producción en profundidad de la arquitectura Kafka

El blog anterior proporcionó una comprensión general del flujo de trabajo básico y el mecanismo de almacenamiento de Kafka. De hecho, se pensó desde la perspectiva única de los sistemas distribuidos. Luego, este blog presenta las estrategias de Kafka relacionadas con el productor. En el análisis final, también proviene del soporte Perspectiva de las características del sistema distribuido [ alta escalabilidad, alta disponibilidad, alta concurrencia, almacenamiento masivo ].

Estrategia de partición

Kafka tiene N réplicas para cada partición de tema, donde N (mayor o igual a 1) es el número de factores de replicación de tema (reproductores de origen). Kafka implementa la conmutación por error automática a través de un mecanismo de copia múltiple.Cuando un corredor falla en el clúster de Kafka, el mecanismo de copia puede garantizar la disponibilidad del servicio. Para cualquier partición, entre sus N réplicas, una réplica es el líder y las otras son seguidores . El líder es responsable de procesar todas las solicitudes de lectura y escritura de la partición, y el seguidor es responsable de replicar pasivamente los datos en el líder.
Inserte la descripción de la imagen aquí

Razón de la partición

¿Por qué particionar? Blog anterior [Kafka de Getting Started a Abandoning Series Three] La arquitectura de Kafka es detallada: el flujo de trabajo y el mecanismo de almacenamiento se han introducido en detalle, enfaticemos nuevamente:

  • Alta escalabilidad : es conveniente expandirse en el clúster. Cada partición se puede ajustar para adaptarse a la máquina donde se encuentra, y un tema puede estar compuesto por múltiples particiones, por lo que todo el clúster puede adaptarse a datos de cualquier tamaño.
  • Alta simultaneidad : la simultaneidad se puede mejorar, ya que se puede leer y escribir en la unidad de partición, y los mensajes se pueden enviar a múltiples particiones de un tema al mismo tiempo
  • Alta disponibilidad : por supuesto, con alta disponibilidad y alta escalabilidad, también esperamos que todo el clúster sea estable y que los mensajes no se pierdan en condiciones concurrentes. Para garantizar la confiabilidad de los datos, tenemos varias copias de cada partición para asegurar No se pierde ningún mensaje. Si el broker donde se encuentra el líder falla o se cae, la partición correspondiente no podrá procesar las solicitudes del cliente porque no hay líder. En este momento, se refleja el rol de la copia: se elegirá un nuevo líder del seguidor y continuará Manejo de solicitudes de clientes

Como se muestra en la figura anterior, las características de nuestro clúster distribuido se pueden reflejar. De hecho, no solo Kafka, sino todo el middleware distribuido tendrá este concepto. Por ejemplo, ElasticSearch también tiene nodos de nodo, indexación, fragmentación y replicación. Correspondiente al agente de Kafka, el tema, la partición y la réplica están todos conectados a Belden.

Principio de zonificación

El productor utiliza el modo push para publicar mensajes en el intermediario, y cada mensaje se agrega a la patición, que es una escritura secuencial en el disco (la escritura secuencial en el disco es más eficiente que las escrituras aleatorias en la memoria y garantiza la tasa de rendimiento de Kafka). Cuando el productor envía un mensaje al corredor, dado que hay particiones, ¿cómo sabemos a qué partición se debe enviar el mensaje del productor? El productor elegirá en qué partición almacenarlo de acuerdo con el algoritmo de partición .
Inserte la descripción de la imagen aquí
De la estructura del código, podemos ver que en realidad se puede resumir en tres métodos, es decir, tres mecanismos de enrutamiento para determinar a qué partición se envía el mensaje. Ellos son:

  1. En el caso de especificar la partición, utilice directamente el valor especificado como valor de partición;
  2. Si no se especifica el valor de la partición pero hay una clave, tome el resto del valor hash de la clave y el número de partición del tema para obtener el valor de la partición
  3. Cuando no hay un valor de partición ni un valor de clave, se genera aleatoriamente un número entero en la primera llamada (se incrementa en este número entero para cada llamada posterior), y este valor y el número total de particiones disponibles para el tema se toman para obtener el valor de la partición. Es el algoritmo llamado "round-robin" [algoritmo de sondeo].

Después de comprender cómo se envían los mensajes a las particiones, hemos resuelto la alta escalabilidad y la alta concurrencia.También debemos pensar en un problema, cómo garantizar una alta escalabilidad, es decir, cómo transmitir datos de manera confiable.

Garantía de fiabilidad de los datos

Para garantizar que los datos enviados por el productor puedan enviarse de manera confiable al tema especificado, cada partición del tema debe enviar un ack (confirmación de reconocimiento) al productor después de recibir los datos enviados por el productor . Si el productor recibe el ack, Envíe la siguiente ronda; de lo contrario, vuelva a enviar los datos.
Inserte la descripción de la imagen aquí

Mecanismo de respuesta ACK [tiempo de envío ACK]

Kafka ofrece a los usuarios tres niveles de confiabilidad. Los usuarios pueden sopesar los requisitos de confiabilidad y latencia. Cuando el productor envía datos al líder, el nivel de confiabilidad de los datos se puede establecer mediante el parámetro request.required.acks:

  1. request.required.acks = 0, el productor envía continuamente datos al líder sin la retroalimentación del líder de los mensajes de éxito. En este caso, la eficiencia de transmisión de datos es la más alta, pero la confiabilidad de los datos es de hecho la más baja. Es posible que se pierdan datos durante el proceso de envío o que se pierdan datos cuando el líder está caído. [ Mayor eficiencia de transmisión, menor confiabilidad ]

  2. request.required.acks = 1, esta es la situación predeterminada, es decir: el productor envía datos al líder, el líder escribe el registro local con éxito y regresa al cliente con éxito; en este momento, otras copias en el ISR no han tenido tiempo de extraer el mensaje, si en este momento Si el líder está abajo, el mensaje enviado esta vez se perderá. [En eficiencia de transmisión, en confiabilidad ]
    Inserte la descripción de la imagen aquí

  3. request.required.acks = -1 (all), el productor envía datos al líder. Después de recibir los datos, el líder espera hasta que todas las copias en la lista ISR hayan sincronizado los datos (consistencia fuerte) antes de devolver un mensaje de éxito al productor. Si no se ha recibido el mensaje de éxito, los datos se reenviarán automáticamente si se considera que no se han enviado. Esta es la solución más confiable, por supuesto, el rendimiento también se verá afectado. [ Baja eficiencia de transmisión y alta confiabilidad ] Al mismo tiempo, si el líder falla después de que se completa la sincronización del seguidor antes de que el corredor envíe un ack, causará la duplicación de datos
    Inserte la descripción de la imagen aquí

Cuando request.required.acks = -1, debe prestar atención. Si desea mejorar la confiabilidad de los datos, mientras configura request.required.acks = -1, también necesita el parámetro min.insync.replicas para cooperar, a fin de maximizar el efecto . min.insync.replicas Este parámetro se utiliza para establecer el número mínimo de réplicas en el ISR. El valor predeterminado es 1. Este parámetro tendrá efecto si y solo cuando el parámetro request.required.acks se establece en -1. Cuando el número de réplicas en el ISR es menor que el número configurado en min.insync.replicas, el cliente devolverá una excepción: org.apache.kafka.common.errors.NotEnoughReplicasExceptoin: Los mensajes se rechazan ya que hay menos réplicas sincronizadas de las necesarias. Al establecer el parámetro min.insync.replicas en 2, cuando el número real de réplicas en el ISR es 1 (solo el líder), no se puede garantizar la confiabilidad, porque si el líder cae después de enviar un ack, entonces el mensaje será Pérdida, por lo que la solicitud de escritura del cliente debe rechazarse para evitar la pérdida de mensajes .

Estrategia de sincronización de réplicas [condición de envío de ACK]

Entonces, ¿cuántas copias de foller se sincronizan antes de enviar un ack? Las dos soluciones existentes eligen la segunda: la primera ocupa demasiados recursos de la máquina, lo que genera una gran cantidad de redundancia de datos y el retraso de la red tiene poco efecto en Kafka.
Inserte la descripción de la imagen aquí

Estrategia de elección de ISR

Después de adoptar el esquema de sincronización de réplica completa, el tiempo de envío de ack se determina de la siguiente manera: el líder recibe los datos y todos los seguidores comienzan a sincronizar los datos , pero imagina la siguiente situación: hay un seguidor, debido a algún tipo de falla, el retraso no se puede sincronizar con el líder, entonces El líder tiene que esperar hasta que complete la sincronización antes de enviar un ack. ¿Cómo resolver este problema? Introducimos el concepto de ISR

  • Todas las copias (réplicas) se denominan colectivamente réplicas asignadas o AR
  • ISR es un subconjunto de AR. El líder mantiene la lista de ISR. Los seguidores tienen cierto retraso en la sincronización de los datos del líder (el umbral de tiempo de espera se establece mediante el parámetro replica.lag.time.max.ms ). Los seguidores que superen el umbral serán excluidos del ISR. depositar OSR (réplicas fuera de sincronización), el seguidor recién agregado se almacenará primero en el OSR en
  • AR = ISR + OSR , es decir, todas las copias = copias disponibles + copias de seguridad .
  • La lista de ISR incluye: líder + seguidores que están sincronizados con el líder. Después de que el líder falle, se elegirá un nuevo líder del ISR

Según este mecanismo, el ISR siempre es un clúster dinámico y estable. Una vez que llega el mensaje, el líder lo lee primero y luego lo envía a cada seguidor para asegurarse de que cada copia del ISR esté en un estado sincronizado. Una vez que el líder cuelga, puede recibirlo inmediatamente del ISR Elija un nuevo líder para procesar el mensaje.

Mecanismo de manejo de fallas [garantía de sincronización de copia]

En la estrategia de aseguramiento de la confiabilidad de los datos, aprendimos cómo garantizar la confiabilidad de los mensajes a través de particiones y réplicas, así como mecanismos dinámicos de ISR y ack. Luego discutiremos en profundidad cómo restaurar el clúster a la normalidad cuando ocurre una falla .

Conceptos básicos de HW y LEO

Inserte la descripción de la imagen aquí
El proceso de flujo de mensajes entre HW y LEO es el siguiente:
Inserte la descripción de la imagen aquí
el mecanismo de replicación de Kafka no es una replicación completamente sincrónica ni una replicación asincrónica pura. De hecho, la replicación sincrónica requiere que todos los seguidores activos se hayan replicado antes de que se confirme este mensaje. Este método de replicación se limita al seguidor más lento, lo que afectará en gran medida la tasa de rendimiento. En el modo de replicación asincrónica, el seguidor replica los datos del líder de forma asincrónica. Siempre que el líder escriba los datos en el registro, se considera que se ha confirmado. En este caso, si el seguidor aún no se ha replicado y está detrás del líder, el líder cae repentinamente. Se perderán datos y se reducirá la confiabilidad. La estrategia de Kafka de usar ISR ha logrado un buen equilibrio entre confiabilidad y rendimiento [ sincronizar la replicación y eliminar las réplicas lentas ]

Mecanismo de sincronización de fallas

Cuando fallan diferentes máquinas, echemos un vistazo a cómo ISR maneja los clústeres y mensajes, que se dividen en fallas de seguidores y fallas de líderes:

  • Si el seguidor falla , el seguidor será expulsado temporalmente del ISR después de que falle. Después de que el seguidor se recupere, el seguidor leerá el último HW registrado en el disco local e interceptará la parte del archivo de registro más alta que el HW, y comenzará desde el HW desde el líder. Sincronizar. Una vez que el LEO del seguidor es mayor o igual que el HW de la partición, es decir, después de que el seguidor alcanza al líder, puedes volver a unirte al ISR.
  • El líder falla . Después de que el líder falla , se seleccionará un nuevo líder del ISR. Después de eso, para garantizar la coherencia de los datos entre varias copias, los seguidores restantes primero cortarán las partes de sus archivos de registro superiores a HW Y luego sincronice los datos del nuevo líder.

Con todo, prevalecerá el HW más reciente que esté sincronizado con todas las copias . Pero esto es solo un método de procesamiento, y no garantiza que los datos no se repitan o se pierdan. Veamos un caso de duplicación de datos: el líder está inactivo : considere un escenario: acks = -1, parte de la copia de ISR completa la sincronización, en este momento el líder Cuelgue, como se muestra en la siguiente figura: follower1 sincroniza los mensajes 4 y 5, follower2 sincroniza el mensaje 4 y, al mismo tiempo, follower2 es elegido como líder.
Inserte la descripción de la imagen aquí
De esta manera, se produce el fenómeno de la duplicación de datos , por lo que el mecanismo HW & LEO solo puede asegurar que las copias estén sincronizadas, pero no puede garantizar que los datos no se repitan o se pierdan. Si quieres asegurar todo, necesitas combinar el nivel ACK

Elección de líder

En caso de una posible falla, cuando el líder se cuelga, debemos elegir un nuevo líder, siguiendo la siguiente estrategia: Kafka mantiene dinámicamente un ISR para cada partición en ZooKeeper, y todas las réplicas en este ISR se sincronizan con el líder. , Solo los miembros de ISR pueden ser elegidos como líderes.

Por supuesto, hay casos extremos : cuando el ISR tiene al menos un seguidor (ISR incluido el líder), Kafka puede estar seguro de que el mensaje de confirmación no se pierde, pero si todas las réplicas de una partición se cuelgan, naturalmente, no se puede garantizar que los datos no se pierdan. ¿Cómo llevar a cabo la elección de líder en este caso? Generalmente hay dos opciones:

  • Espere a que se recupere cualquier réplica en el ISR y elíjala como líder [ alta confiabilidad ]
  • Seleccione la primera réplica recuperada (no necesariamente en el ISR) como líder [ alta disponibilidad ]

Si debe esperar a que se recupere la réplica en el ISR, el tiempo no disponible puede ser relativamente largo. Y si no se pueden recuperar todas las réplicas en el ISR o se pierden los datos, esta partición nunca estará disponible. Seleccione la primera réplica recuperada como líder. Si esta réplica no es la réplica en el ISR, es posible que no tenga todos los mensajes confirmados, lo que provocará la pérdida de mensajes. De forma predeterminada, Kafka usa la segunda estrategia, unclean.leader.election.enable = true, o puede establecer este parámetro en false para habilitar la primera estrategia

Exactamente una vez semántica

Después de comprender el mecanismo de recuperación de fallas para garantizar la sincronización entre las réplicas y el mecanismo ACK para garantizar la confiabilidad de los datos , analicemos cómo garantizar la idempotencia de la transmisión de datos.

  • Establecer el nivel ACK del servidor en -1 puede garantizar que no se pierdan datos entre el productor y el servidor, es decir, la semántica de AtLeast Once. AtLeast Once puede garantizar que los datos no se pierdan, pero no puede garantizar que los datos no se repitan
  • Establecer el nivel de ACK del servidor en 0 puede garantizar que cada mensaje del productor solo se envíe una vez, es decir, la semántica de At Most Once

Para información muy importante, los consumidores requieren que los datos no se repitan ni se pierdan, es decir, la semántica Exactamente una vez. Kafka antes de la versión 0.11 no puede hacer nada al respecto. Solo puede garantizar que los datos no se pierdan, y luego los consumidores intermedios eliminarán los datos duplicados a nivel mundial. En el caso de múltiples aplicaciones posteriores, cada una debe deduplicarse individualmente a nivel mundial, lo que tiene un gran impacto en el rendimiento.

Idempotencia

La versión 0.11 de Kafka introdujo una característica importante: la idempotencia. La llamada idempotencia significa que no importa cuántas veces el Productor envíe datos repetidos al servidor, el servidor solo conservará uno. La idempotencia combinada con la semántica de Al menos una vez constituye la semántica Exactamente una vez de Kafka. Es decir: Al menos una vez + idempotencia = Exactamente una vez

Para habilitar la idempotencia, solo necesita establecer enable.idompotence en el parámetro de Producer en verdadero. La realización de la idempotencia de Kafka es en realidad reemplazar las necesidades originales descendentes a los datos ascendentes. Al Productor con idempotencia activada se le asignará un PID cuando se inicialice, y el mensaje enviado a la misma Partición irá acompañado de un Número de Secuencia. El Broker almacenará en caché <PID, Partition, SeqNumber>. Cuando se envía un mensaje con la misma clave primaria, el Broker solo conservará una. Pero el PID cambiará cuando se reinicie, y las diferentes particiones también tienen diferentes claves primarias, por lo que la idempotencia no puede garantizar exactamente una vez entre las particiones y sesiones .

Asuntos del productor

Para lograr una transacción de datos de sesión cruzada entre particiones y evitar la duplicación de PID causada por el reinicio, es necesario introducir un ID de transacción único a nivel mundial del tema y vincular el ID y la transacción adquiridos por el productor de PID . De esta manera, cuando se reinicia el Producer, el PID original se puede obtener a través del TransactionID en curso. Para gestionar la transacción, Kafka introdujo un nuevo componente Coordinador de transacciones. El Productor obtiene el estado de la tarea correspondiente al ID de la transacción al interactuar con el Coordinador de la transacción. El Coordinador de la transacción también es responsable de escribir todas las transacciones en un tema interno de Kafka, de modo que incluso si se reinicia todo el servicio, dado que se guarda el estado de la transacción, se puede restaurar el estado de la transacción en curso. Para continuar.

para resumir

Este blog describe en detalle la estrategia de productor de Kafka, desde el mecanismo de partición hasta el mecanismo de confiabilidad de los datos, el mecanismo de recuperación de fallas y, finalmente, cómo implementar la semántica exacta de una vez del mensaje. Siente que la estrategia principal de Kafka todavía se concentra en el lado del productor. Es más complicado de entender. Sin embargo, es beneficioso intercambiar recursos con la programación. Es beneficioso ahorrar recursos mediante una programación compleja.

Parte del contenido se cita de https://gitbook.cn/books/5ae1e77197c22f130e67ec4e/index.html

Supongo que te gusta

Origin blog.csdn.net/sinat_33087001/article/details/108397968
Recomendado
Clasificación