Estructura interna de Kafka

Inserte la descripción de la imagen aquí
Soy aburrido. Después de tres días y dos noches, finalmente entendí la estructura interna de Kafka. Leí muchos artículos antes y no estaba claro, y todavía no tenía una composición clara en mi mente ...

1. Introducción a Kafka

Apache Kafka era originalmente un sistema de mensajería distribuida de código abierto de LinkedIn, ahora es un subproyecto de Apache y se ha convertido en uno de los sistemas de mensajería más utilizados en el campo del código abierto. La comunidad de Kafka es muy activa. Desde la versión 0.9, el eslogan de Kafka ha cambiado de "un sistema de mensajería distribuida de alto rendimiento" a "una plataforma de transmisión distribuida".

Kafka se diferencia de los sistemas de mensajería tradicionales en:

  • Kafka es un sistema distribuido que es fácil de escalar.
  • Proporciona un alto rendimiento tanto para publicar como para suscribirse.
  • Admite múltiples suscriptores y equilibra automáticamente a los consumidores cuando falla
  • Resistencia informada

2. Composición del núcleo de Kafka

Inserte la descripción de la imagen aquí
Como se muestra arriba: puede ver el productor, el corredor, el tema, la partición, el grupo de consumidores, el consumidor y otros componentes.

En un conjunto de arquitectura Kafka, hay varios Productores, varios Corredores y varios Consumidores. Cada Productor puede corresponder a varios Temas y cada Consumidor sólo puede corresponder a un Grupo de Consumidores.

Componente Introducción
Productor Productor de mensajes: el cliente que envía mensajes al Broker.
Productor Consumidor de mensajes: cliente que lee mensajes del intermediario
Corredor Nodo de procesamiento de mensajes intermedio: un nodo de Kafka es un intermediario, uno o más intermediarios pueden formar un clúster de Kafka (generalmente se recomienda un número impar de clústeres, al menos tres)
Tema Tema: cada mensaje publicado en el clúster de Kafka debe especificar un tema, y ​​los mensajes de Kafka se almacenan en el tema.
Dividir Partición: un concepto de almacenamiento físico. Un tema se puede dividir en varias particiones. Cada partición está ordenada internamente, pero los datos combinados por varias particiones no están ordenados.
Grupo de consumidores Grupo de consumidores: cada consumidor pertenece a un grupo de consumidores (CG) específico, se puede enviar un mensaje a varios CG diferentes, pero los datos de la misma partición solo pueden ser consumidos por un consumidor en el CG

Aquí hay algunas explicaciones más detalladas de algunos componentes:

2.0 Guardián del zoológico

cuidadores del zoológico (responsables de elección, balance, meta registros, registros de consumo)

Zookeeper interactúa con los intermediarios y los consumidores del clúster para mantener los datos y la alta disponibilidad del clúster.

  • Registre la información de ubicación de los mensajes de consumo del consumidor;
  • Elección de líder cuando fallan las particiones
  • Cómo almacenar la metainformación de Kafka en zookeeper

Nota: El productor no está registrado en zk, el consumidor está registrado en zk.

El diagrama de estructura de kafka en zookeeper es el siguiente:
Inserte la descripción de la imagen aquí

2.1 Partición (expansión horizontal, alta concurrencia)

Kafka mantiene un archivo de registro de partición distribuido para cada tema, y ​​cada partición es un registro de anexos en el nivel de almacenamiento de Kafka. Cualquier mensaje publicado en esta partición se agregará al final del archivo de registro. A cada mensaje de la partición se le asignará un número de secuencia que aumenta monótonamente en orden cronológico, que es nuestro desplazamiento, que es un número largo. A través de este desplazamiento, puede determinar un mensaje único en la partición. El orden está garantizado bajo la partición, pero el orden no está garantizado bajo el tema.
Inserte la descripción de la imagen aquí

En respuesta a lo que dice la tabla anterior: cada partición está ordenada internamente, pero los datos combinados por múltiples particiones no están ordenados

Cuando el productor de mensajes envía un mensaje:

  • Si se especifica una patición, la patición se usa directamente
  • No se especifica ninguna patición, pero se especifica la clave, el valor de clave realiza el hash y el resto del número de particiones se toma para garantizar que el mismo valor de clave se enrute a la misma partición. Si desea una coherencia de orden sólida en la cola, puede permitir que todos los mensajes Ambos estén configurados con la misma clave.
  • No se especifica ni la patición ni la clave, utilice el sondeo para seleccionar una patición

Inserte la descripción de la imagen aquí
Razón de la partición:

1. Es conveniente expandir horizontalmente en el clúster. Cada patición se puede ajustar para adaptarse a la máquina donde se encuentra, y un tema puede estar compuesto por múltiples paticiones, por lo que todo el clúster puede adaptarse a datos de cualquier tamaño.

2. Se puede mejorar la alta concurrencia porque se puede leer y escribir en unidades de patición. (Se pueden distribuir varias solicitudes en diferentes versiones)

2.2 Mecanismo de copia (alta disponibilidad)

En la imagen de arriba, puede ver: Mensajes de administración de clúster de Kafka. Hay tres Brokers en esta capa. Entre ellos, hay un TopicA en Broker1, pero este TopicA tiene dos particiones: Partition0, Partition1

Como se menciona en la tabla anterior, un tema puede tener múltiples particiones

Como puede ver, también hay un TopicA en Broker2, y este TopicA también tiene dos particiones: Partition0 y Partition1.

En Broker1: Partition0 es Leader, Partition1 es Follower,
pero en Broker2: Partition0 es Follower, Partition1 es Leader

Llamamos Partition0 en Broker2 una copia de Partition0 en Broker1. De hecho, ambos pueden llamarse copias, y Partition0 en Broker1 es la copia maestra.

Pregunta: ¿Por qué poner la copia de Partition0 en Broker2?

Respuesta: Le pregunto, si pone Líder y Seguidor en la misma máquina, entonces, cuando esta máquina cuelga, ¿no es porque los datos en esta partición se han ido? ¿Para qué necesitas una copia?

El mecanismo de replicación de Kafka es que varios nodos de servidor replican los registros de las particiones de temas de otros nodos. Cuando falla un nodo en el clúster, la solicitud para acceder al nodo fallido se transferirá a otros nodos normales (este proceso generalmente se llama Reblance), y cada partición de cada tema en Kafka tiene una copia maestra y 0 o más La réplica, la réplica mantiene los datos sincronizados con la réplica principal y se reemplazará cuando la réplica principal falle.

La misma patición puede tener múltiples replicaciones (correspondientes a default.replication.factor = N en el archivo de configuración server.properties). Sin replicación, una vez que el Broker deja de funcionar, no se pueden consumir todos los datos del patrón y el productor ya no puede almacenar datos en el patrón. Después de la introducción de la replicación, la misma patición puede tener múltiples replicaciones. En este momento, se debe seleccionar un líder entre estas replicaciones. El productor y el consumidor solo interactúan con este líder, y otras replicaciones actúan como seguidores para copiar datos del líder .

En Kafka, no todas las réplicas se pueden utilizar para reemplazar la réplica principal, por lo que se mantiene un conjunto ISR (In sync Replicas) en el nodo líder de Kafka, que también se denomina conjunto in sync. La necesidad en este conjunto Dos condiciones son reunió:

  • El nodo debe permanecer conectado a ZK
  • Durante el proceso de sincronización, esta copia no puede estar muy por detrás de la copia maestra

El ISR almacena las ubicaciones donde existen todas las copias, como: [0,2,1], similar a este almacenamiento de estructura, donde 0, 2, 1 representan el ID del corredor (este ID es único)


[0,2, 1 ]: Indica que el Líder actual está en la máquina con ID 0, 2, 1 significa la máquina donde se encuentran las otras dos copias.


Nota: De hecho, no es descabellado que 2 esté delante de 1, lo que significa que la copia de la máquina con ID 2 está más cerca de la copia maestra, cuando el líder cuelga, 2 será elegido como el nuevo líder.

Pregunta: Se informa de un error cuando Kafka establece un número de réplicas mayor que Broker.

Solución: Como se mencionó anteriormente, las copias de Kafka se almacenan en diferentes Brokers. Si el número de copias es mayor que el número de Brokers, en este momento hay al menos dos copias del mismo Broker, entonces ¿cuál es el punto?

2.3 Almacenamiento de registros de alto rendimiento

Todos los mensajes de un tema en Kafka se distribuyen y almacenan en varios nodos en forma de partición. Al mismo tiempo, en la máquina Kafka, cada partición corresponde realmente a un directorio de registro y hay varios segmentos de registro (LogSegment) bajo el directorio. El archivo LogSegment consta de dos partes, a saber, el archivo ".index" y el archivo ".log", que se representan respectivamente como el archivo de índice de segmento y el archivo de datos. Las reglas de comando para estos dos archivos son: el primer segmento de la partición global comienza desde 0, y cada archivo de segmento subsiguiente se denomina valor de compensación del último mensaje del archivo de segmento anterior, el tamaño del valor es de 64 bits y la longitud del número es de 20 bits. Ningún número se rellena con 0, de la siguiente manera, asumiendo que hay 1000 mensajes, cada tamaño de segmento de registro es 100, a continuación se muestra el índice y el registro de 900-1000:
Inserte la descripción de la imagen aquí

Dado que los datos del mensaje de Kafka son demasiado grandes, si se compilan todos los índices, ocupará espacio y aumentará el tiempo. Por lo tanto, Kafka elige el método de índice disperso, de modo que el índice pueda ingresar directamente a la memoria para acelerar la velocidad de consulta parcial. .

Introduzca brevemente cómo leer los datos. Si queremos leer los datos del 911, el primer paso es averiguar a qué segmento pertenece, y encontrar el archivo al que pertenece según la dicotomía. Después de encontrar 0000900.index y 00000900. log, Luego vaya al índice para encontrar el índice (911-900) = 11 o el índice más cercano menor que 11. Aquí encontramos que el índice es [10,1367] a través de la dicotomía, y luego pasamos la posición física de este índice 1367 y comience a buscar más tarde hasta que encuentre los datos del 911.

Lo anterior trata sobre el proceso de buscar un cierto desplazamiento, pero la mayoría de las veces no necesitamos encontrar un determinado desplazamiento, solo necesitamos leer en orden, y en el orden de lectura, el sistema operativo agregará entre la memoria y el disco Page cahe, que es la operación de lectura previa que solemos ver, por lo que nuestra operación de lectura secuencial es muy rápida. Pero Kafka tiene un problema. Si hay demasiadas particiones, habrá muchos segmentos de registro. Cuando la escritura se realiza en lotes, en realidad se convertirá en escritura aleatoria. La E / S aleatoria tiene un gran impacto en el rendimiento en este momento. Entonces, en términos generales, Kafka no puede tener demasiadas particiones. En respuesta a esto, RocketMQ escribe todos los registros en un archivo, que puede convertirse en escritura secuencial. Con ciertas optimizaciones, la lectura puede estar cerca de la lectura secuencial.

Piénselo: 1. ¿Por qué necesitamos particionar, es decir, el tema tiene una sola partición, no es así? 2. ¿Por qué es necesario segmentar el registro?

1. La partición es para expansión horizontal 2. Si el registro es demasiado grande en el mismo archivo, afectará el rendimiento. Si el registro crece indefinidamente, la velocidad de la consulta se ralentizará.

3. Modelo de consumo

Una vez que el productor envía el mensaje al clúster de Kafka, el consumidor lo consumirá. De manera general, existen dos tipos de modelos de consumo: empujar y tirar

Basado en el sistema de mensajes del modelo push, el agente de mensajes registra el estado de consumo. Después de que el agente de mensajes envía el mensaje al consumidor, marca el mensaje como consumido, pero este método no puede garantizar bien la semántica de procesamiento del consumo. Por ejemplo, cuando enviamos un mensaje al consumidor, el proceso de consumo se cuelga o no se recibe el mensaje por motivos de la red, si lo marcamos como consumido en el agente de consumo, el mensaje se perderá definitivamente. Si usamos este método de respuesta después de que el productor recibe el mensaje, el agente de mensajes necesita registrar el estado de consumo, lo cual no es deseable. Si se usa push, la tasa de consumo de mensajes está completamente controlada por el agente consumidor. Una vez que el consumidor está bloqueado, se producirán problemas.

Kafka adopta un modelo pull (encuesta) para controlar la velocidad del consumo y el progreso del consumo por sí mismo, y los consumidores pueden consumir de acuerdo con cualquier compensación. Por ejemplo, los consumidores pueden consumir mensajes que ya se han consumido para su reprocesamiento, o consumir mensajes recientes, etc.
Inserte la descripción de la imagen aquí

Cuando el productor envía datos al líder, el nivel de confiabilidad de los datos se puede establecer a través del parámetro request.required.acks: (la figura anterior es para el proceso -1)

  • 0: Significa que el productor no espera la confirmación de la finalización de la sincronización del intermediario y continúa enviando el siguiente mensaje (lote),
    proporcionando el retraso más bajo. Pero la durabilidad más débil, cuando el servidor falla, es probable que se produzcan pérdidas de datos . Por ejemplo, si el líder está muerto, el productor continuará enviando mensajes sin saberlo y el corredor perderá los datos si no los recibe.

  • 1: Significa que el productor espera a que el líder reciba con éxito los datos y obtenga la confirmación antes de enviar el siguiente mensaje. Esta opción proporciona una mayor durabilidad y menor latencia.

    El líder de la partición muere, el siguiente no se ha copiado, los datos se perderán

  • -1: significa que el productor obtiene la confirmación del seguidor antes de enviar el siguiente dato

    La durabilidad es la mejor y la latencia es la peor.

El rendimiento de los tres mecanismos está disminuyendo y la confiabilidad está aumentando.

4. Estrategia de almacenamiento

No importa si el mensaje se consume o no, Kafka conservará el mensaje, lo que significa que el mensaje se puede consumir repetidamente.

Hay dos estrategias para eliminar datos antiguos:

  1. Basado en el tiempo: log.retention.hours = 168 (en el archivo de configuración: una semana de datos se guarda de forma predeterminada)
  2. Según el tamaño: log.retention.bytes = 1073741824 (1G)

Cabe señalar que debido a que Kafka lee una complejidad de hora específica de O (1), es decir, no tiene nada que ver con el tamaño del archivo, por lo que eliminar archivos caducados aquí no tiene nada que ver con mejorar el rendimiento de Kafka.

Supongo que te gusta

Origin blog.csdn.net/RookiexiaoMu_a/article/details/105452515
Recomendado
Clasificación