Kafka: explicación detallada del mecanismo de réplica
El llamado mecanismo de copia (Replicación), que también puede denominarse mecanismo de copia de seguridad, generalmente se refiere a un sistema distribuido que guarda la misma copia de datos en múltiples máquinas conectadas a la red. ¿Cuáles son los beneficios del mecanismo de copia?
Estas ventajas se mencionan con mayor frecuencia en los libros de texto de sistemas distribuidos, pero desafortunadamente, para Apache Kafka, solo puede disfrutar del primer beneficio que brinda el mecanismo de copia, es decir, proporcionar redundancia de datos para lograr alta disponibilidad y. alta durabilidad. Explicaré en detalle por qué Kafka no proporciona los beneficios 2 y 3 más adelante en esta conferencia.
Pero aun así, el mecanismo de réplica sigue siendo el núcleo de la arquitectura de diseño de Kafka. También es una piedra angular importante para garantizar la alta disponibilidad del sistema y la alta durabilidad de los mensajes.
Antes de discutir el mecanismo de copia específico, primero tomemos un momento para aclarar el significado de copia.
Como mencionamos antes, Kafka tiene el concepto de temas, y cada tema se divide en varias particiones. En realidad, el concepto de réplicas se define a nivel de partición y cada partición se configura con varias réplicas.
La llamada réplica (Réplica) es esencialmente un registro de envío que solo puede agregar mensajes. Según la definición del mecanismo de réplica de Kafka, todas las réplicas en la misma partición guardan la misma secuencia de mensajes. Estas réplicas están dispersas y almacenadas en diferentes Brokers, lo que puede resistir la falta de disponibilidad de datos causada por el tiempo de inactividad de algunos Brokers.
En un entorno de producción real, cada Broker puede guardar diferentes copias de diferentes particiones en cada tema. Por lo tanto, es muy normal que un solo Broker tenga cientos o miles de copias.
A continuación, veamos una imagen que muestra la distribución de réplicas en un clúster Kafka con tres Brokers. En esta imagen, podemos ver que las tres copias de la partición 0 del tema 1 están distribuidas en tres Brokers, y las copias de otras particiones de temas también están dispersas en diferentes Brokers para lograr la redundancia de datos.
Dado que se pueden configurar varias copias en una partición y el contenido de estas copias debe ser coherente, una pregunta natural es: ¿Cómo podemos garantizar que todos los datos de las copias sean coherentes? Especialmente para Kafka, cuando un productor envía un mensaje a un tema, ¿cómo se sincroniza el mensaje con todas las réplicas correspondientes? Para abordar este problema, la solución más común es utilizar un mecanismo de copia basado en líder. Apache Kafka está diseñado así.
El principio de funcionamiento del mecanismo de copia basado en líder se muestra en la siguiente figura. Permítanme explicar brevemente el contenido de esta figura.
Primero, en Kafka, las réplicas se dividen en dos categorías: réplica líder (Leader Replica) y réplica seguidora (Follower Replica). Cuando se crea cada partición, se elige una réplica, denominada réplica líder, y las réplicas restantes se denominan automáticamente réplicas seguidoras.
En segundo lugar, el mecanismo de copia de Kafka es más estricto que el de otros sistemas distribuidos. En Kafka, las réplicas de seguidores no brindan servicios al mundo exterior. Esto significa que ninguna copia de seguidor puede responder a solicitudes de lectura y escritura de consumidores y productores. Todas las solicitudes deben ser procesadas por la réplica líder, o en otras palabras, todas las solicitudes de lectura y escritura deben enviarse al Broker donde se encuentra la réplica líder, y el Broker es responsable del procesamiento. La copia seguidora no procesa las solicitudes de los clientes. Su única tarea es extraer mensajes de forma asincrónica de la copia líder y escribirlos en su propio registro de confirmación para lograr la sincronización con la copia líder.
En tercer lugar, cuando la copia líder muere o el Broker donde se encuentra la copia líder deja de funcionar, Kafka confía en la función de monitoreo proporcionada por ZooKeeper para detectarlo en tiempo real e inmediatamente iniciar una nueva ronda de Leader. elección, elija uno de las copias de seguidores como nuevo líder. Una vez reiniciada la copia líder anterior, solo se puede agregar al clúster como copia seguidora.
Debes prestar especial atención al segundo punto anterior, es decir, las copias de seguidores no prestan servicios al mundo exterior. ¿Recuerda que cuando acabamos de hablar de los beneficios del mecanismo de réplica dijimos que Kafka no pudo proporcionar una expansión horizontal de las operaciones de lectura y mejorar la localidad? La razón específica radica en esto.
Para los usuarios del cliente, la copia seguidora de Kafka no tiene ningún efecto. No puede ayudar a que la copia líder sea "resistente a la lectura" como MySQL, ni puede colocar algunas copias fuera del cliente para mejorar la localidad de los datos. .
En este caso, ¿por qué Kafka está diseñado de esta manera? De hecho, este mecanismo de copia tiene dos beneficios.
1. Implemente cómodamente "Lea sus escrituras".
El llamado Read-your-writes, como sugiere el nombre, es que después de usar la API del productor para escribir con éxito un mensaje en Kafka, use inmediatamente la API del consumidor para leer el mensaje que acaba de producir.
Por ejemplo, cuando publicas una publicación en Weibo, definitivamente querrás verla inmediatamente después de publicar una publicación en Weibo. Este es un escenario típico de lectura de escrituras. Si a la copia seguidora se le permite proporcionar servicios externos, dado que la sincronización de la copia es asincrónica, es posible que la copia seguidora aún no haya extraído el último mensaje de la copia líder, por lo que el cliente no puede ver el último mensaje escrito.
2. Implemente cómodamente lecturas monótonas.
¿Qué es la lectura monótona? Es decir, para un usuario consumidor, cuando consume mensajes varias veces, no verá que un determinado mensaje existe por un tiempo y no existe por un tiempo.
Si la réplica seguidora puede proporcionar servicios de lectura, supongamos que actualmente hay 2 réplicas seguidoras F1 y F2, que extraen los datos de la réplica líder de forma asincrónica. Si F1 obtiene las últimas noticias del Líder pero F2 aún no las ha obtenido a tiempo, entonces si un consumidor lee primero el mensaje de F1 y luego extrae el mensaje de F2, puede ver el siguiente fenómeno: Las últimas noticias vistas durante un Falta consumo durante el segundo consumo. Esta no es una coherencia de lectura monótona. Sin embargo, si el líder procesa todas las solicitudes de lectura, Kafka puede lograr fácilmente una coherencia de lectura monótona.
Como acabamos de decir repetidamente, la copia seguidora no proporciona servicios, solo extrae datos de la copia líder de forma asincrónica y regular. Al ser asíncrono, existe el riesgo de que sea imposible sincronizarlo con el Líder en tiempo real. Antes de discutir cómo abordar adecuadamente este riesgo, debemos saber exactamente qué significa sincronización. En otras palabras, Kafka necesita decirnos claramente bajo qué condiciones la copia del seguidor está sincronizada con el líder.
Basado en esta idea, Kafka introdujo las réplicas sincronizadas, también conocidas como conjuntos de réplicas ISR. Las réplicas en el ISR son todas réplicas que están sincronizadas con el Líder. Por el contrario, las réplicas de los seguidores que no están en el ISR se consideran no sincronizadas con el Líder. Entonces, ¿qué tipo de copia puede ingresar al ISR?
Lo primero que debemos dejar claro es que la copia del Líder está naturalmente en el ISR. En otras palabras, ISR no es solo un conjunto de réplicas de seguidores, debe incluir réplicas de líderes. Incluso en algunos casos, el ISR sólo cuenta con una copia del Líder.
Además, las copias de seguidores que pueden ingresar al ISR deben cumplir ciertas condiciones. En cuanto a cuáles son las condiciones, primero déjame darte una pista. Echemos un vistazo a la imagen a continuación.
Hay 3 réplicas en el diagrama: 1 réplica líder y 2 réplicas seguidoras. La réplica Líder ha escrito actualmente 10 mensajes, la réplica Seguidor1 ha sincronizado 6 de ellos y la réplica Seguidor2 solo ha sincronizado 3 de ellos. Ahora, piénselo, para estas dos copias de seguidores, ¿qué copia de seguidores cree que no está sincronizada con el Líder?
La respuesta es que depende de la situación específica. En inglés, es la famosa frase "Depende". Parece que Follower2 tiene muchos menos mensajes que Leader y es muy probable que no esté sincronizado con Leader. De hecho, este es el caso, pero sólo es posible.
De hecho, las dos copias del Seguidor en esta imagen pueden no estar sincronizadas con el Líder, pero también pueden estar sincronizadas con el Líder. En otras palabras, el criterio de Kafka para juzgar si el Seguidor está sincronizado con el Líder no es la cantidad de mensajes que difieren, sino que hay otro "misterio".
Este estándar es el valor del parámetro replica.lag.time.max.ms del parámetro del lado del Broker. El significado de este parámetro es el intervalo de tiempo máximo que la copia del seguidor puede retrasarse con respecto a la copia del líder. El valor predeterminado actual es de 10 segundos. Es decir, siempre que una copia del seguidor vaya por detrás de la copia del líder durante más de 10 segundos consecutivos, Kafka considera que la copia del seguidor está sincronizada con el líder, incluso si los mensajes guardados en la copia del seguidor son significativamente menores que los mensajes. en la copia líder.
Como dijimos antes, el único trabajo de la copia del Seguidor es extraer continuamente mensajes de la copia del Líder y luego escribirlos en su propio registro de confirmación. Si la velocidad de este proceso de sincronización continúa siendo más lenta que la velocidad de escritura del mensaje de la copia líder, luego del tiempo replica.lag.time.max.ms, se considerará que la copia seguidora no está sincronizada con la copia líder. y por lo tanto ya no se puede colocar en el ISR. En este momento, Kafka reducirá automáticamente el conjunto de ISR y "expulsará" la copia del ISR.
Vale la pena señalar que si la copia se pone al día lentamente con el progreso del Líder, se puede volver a agregar al ISR. Esto también muestra que ISR es un conjunto ajustado dinámicamente en lugar de estático.
Dado que el ISR se puede ajustar dinámicamente, naturalmente puede ocurrir una situación como esta: el ISR está vacío. Debido a que la copia del Líder está naturalmente en el ISR, si el ISR está vacío, significa que la copia del Líder también ha "muerto" y Kafka necesita reelegir un nuevo Líder. Pero el ISR está vacío ¿Cómo elegir un nuevo Líder en este momento?
Kafka se refiere a todas las réplicas supervivientes que no están en el ISR como réplicas asincrónicas. En términos generales, las réplicas asincrónicas van demasiado por detrás del líder, por lo que si estas réplicas se seleccionan como el nuevo líder, puede ocurrir una pérdida de datos. Después de todo, los mensajes guardados en estas réplicas van muy por detrás de los del antiguo Leader. En Kafka, el proceso de elección de tales réplicas se llama elección de líder inmundo. El parámetro del lado del intermediario unclean.leader.election.enable controla si se permite la elección de líder no limpio.
Activar la elección de líder no limpia puede causar pérdida de datos, pero la ventaja es que permite que la copia del líder de la partición exista siempre sin detener los servicios externos, mejorando así la alta disponibilidad.
Por el contrario, la ventaja de desactivar la elección de líder Unclean es que mantiene la coherencia de los datos y evita la pérdida de mensajes, pero sacrifica la alta disponibilidad.
Si ha oído hablar de la teoría CAP, debe saber que un sistema distribuido generalmente solo puede satisfacer dos de consistencia (Consistencia), disponibilidad (Disponibilidad) y tolerancia de partición (Tolerancia de partición) al mismo tiempo. . Obviamente, Kafka te da derecho a elegir C o A en este tema.
Puedes decidir si habilitar la elección de líder inmundo en función de tu escenario empresarial real. Sin embargo, le recomiendo encarecidamente que no lo habilite. Después de todo, existen otras formas de mejorar la alta disponibilidad. Si se sacrifica la coherencia de los datos por esta mejora en la alta disponibilidad, no vale la pena.