tutorial quickstart kafka distributed apache-kafka

distributed - quickstart - En Apache Kafka, ¿por qué no puede haber más instancias de consumidores que particiones?



kafka vs rabbitmq (4)

En Kafka, solo una instancia de consumidor puede consumir mensajes de una partición. Si las instancias de los consumidores son más que particiones, no habrá uso de instancias de consumidores adicionales. Entonces kafka no permite estas instancias adicionales de los consumidores.

Ahora bien, si varios consumidores pueden consumir una partición, entonces no habría ningún pedido en el consumo de mensajes. Esta es la razón por la cual kafka no permite múltiples consumidores por partición

Estoy aprendiendo sobre Kafka, leyendo la sección de introducción aquí

https://kafka.apache.org/documentation.html#introduction

específicamente la porción sobre Consumidores. En el penúltimo párrafo de la Introducción, se lee

Kafka lo hace mejor. Al tener una noción de paralelismo -la partición- dentro de los temas, Kafka puede proporcionar garantías de pedido y equilibrio de carga sobre un conjunto de procesos de consumo. Esto se logra asignando las particiones en el tema a los consumidores en el grupo de consumidores, de modo que cada partición sea consumida por exactamente un consumidor en el grupo. Al hacer esto, nos aseguramos de que el consumidor sea el único lector de esa partición y consuma los datos en orden. Como hay muchas particiones, esto todavía equilibra la carga en muchas instancias de consumidores. Sin embargo, tenga en cuenta que no puede haber más instancias de consumidor que particiones.

Mi confusión surge de esa última oración, porque en la imagen justo encima de ese párrafo donde el autor representa dos grupos de consumidores y un tema de 4 particiones, ¡hay más instancias de consumidores que particiones!

Tampoco tiene sentido que no pueda haber más instancias de consumidor que particiones, porque entonces las particiones serían increíblemente pequeñas y parece que la sobrecarga en la creación de una nueva partición para cada instancia de consumidor empantanaría a Kafka. Entiendo que las particiones se usan para tolerancia a fallas y para reducir la carga en cualquier servidor, pero la oración anterior no tiene sentido en el contexto de un sistema distribuido que se supone que puede manejar miles de consumidores a la vez.


Es importante recordar que Kafka mantiene una compensación por [consumidor-grupo, tema, partición]. Esa es la razón.

Supongo que la oración

Sin embargo, tenga en cuenta que no puede haber más instancias de consumidor que particiones.

se refiere al modo de "reequilibrio automático del grupo de consumidores", el modo de consumidor predeterminado cuando acaba de suscribir () cierto número de consumidores a una lista de temas.

Supongo que porque, al menos con Kafka 0.9.x, nada impide tener varias instancias del consumidor, miembros del mismo grupo, leyendo desde la misma partición.

Puedes hacer algo como esto en dos o más hilos diferentes

Properties props = new Properties(); props.put(ConsumerConfig.GROUP_ID_CONFIG, "MyConsumerGroup"); props.put("enable.auto.commit", "false"); consumer = new KafkaConsumer<>(props); TopicPartition partition0 = new TopicPartition("mytopic", 0); consumer.assign(Arrays.asList(partition0)); ConsumerRecords<Integer, String> records = consumer.poll(1000);

y tendrá dos (o más) consumidores leyendo desde la misma partición.

Ahora, el "problema" es que ambos consumidores compartirán la misma compensación, no tienes otra opción ya que solo hay un grupo, tema y partición en juego.

Si ambos consumidores leen el desplazamiento actual al mismo tiempo, ambos leerán el mismo valor, y ambos recibirán los mismos mensajes.

Si desea que cada consumidor lea diferentes mensajes, deberá sincronizarlos para que solo uno pueda obtener y confirmar el desplazamiento en el momento.


Hay una razón por la cual Kafka no puede admitir múltiples consumidores por partición.

El corredor de Kafka escribe datos en el archivo por partición. Entonces, digamos que si dos particiones están configuradas, el intermediario creará dos archivos y asignará múltiples grupos de consumidores a los que se pueden enviar mensajes.

Ahora, para cada partición, solo un consumidor consume mensajes según el desplazamiento del archivo. por ejemplo, el Consumidor 1 leerá primero los mensajes de la compensación de archivos 0 a 4096. Ahora estas compensaciones son parte de la carga útil, de modo que el consumidor sabrá qué compensación usar mientras solicita la lectura de los próximos mensajes.

Si varios consumidores leen desde la misma partición, el consumidor 1 lee del archivo con compensación 0-4096, pero el consumidor 2 aún intentará leer del desplazamiento 0 a menos que también reciba un mensaje enviado al consumidor 1. Ahora, si se envían los mismos mensajes a múltiples consumidores que no es un equilibrio de carga, por lo que Kafka los ha dividido en grupos de consumidores para que todos los grupos de consumidores puedan recibir mensajes, pero dentro del grupo de consumidores, solo un consumidor puede recibir mensajes.


Ok, para entenderlo, uno necesita entender varias partes.

  1. Para poder ordenar el pedido total, el mensaje puede enviarse solo a un consumidor. De lo contrario, sería extremadamente ineficiente, porque tendría que esperar a que todos los consumidores reciban el mensaje antes de enviar el siguiente:

Sin embargo, aunque el servidor distribuye los mensajes en orden, los mensajes se entregan de manera asincrónica a los consumidores, por lo que pueden llegar a ser erróneos para diferentes consumidores. Esto efectivamente significa que el orden de los mensajes se pierde en presencia de consumo paralelo. Los sistemas de mensajería a menudo trabajan en torno a esto teniendo una noción de "consumidor exclusivo" que permite que solo un proceso consuma desde una cola, pero por supuesto esto significa que no hay paralelismo en el procesamiento.

Kafka lo hace mejor. Al tener una noción de paralelismo -la partición- dentro de los temas, Kafka puede proporcionar garantías de pedido y equilibrio de carga sobre un conjunto de procesos de consumo. Esto se logra asignando las particiones en el tema a los consumidores en el grupo de consumidores, de modo que cada partición sea consumida por exactamente un consumidor en el grupo. Al hacer esto, nos aseguramos de que el consumidor sea el único lector de esa partición y consuma los datos en orden. Como hay muchas particiones, esto todavía equilibra la carga en muchas instancias de consumidores. Sin embargo, tenga en cuenta que no puede haber más instancias de consumidor que particiones.

Kafka solo proporciona un orden total sobre los mensajes dentro de una partición, no entre las diferentes particiones de un tema.

También lo que crees que es una penalización de rendimiento (particiones múltiples) es en realidad una ganancia de rendimiento, ya que Kafka puede realizar acciones de diferentes particiones completamente en paralelo, mientras espera que otras particiones finalicen.

  1. La imagen muestra diferentes grupos de consumidores, pero la limitación de un consumidor máximo por partición solo está dentro de un grupo. Aún puede tener múltiples grupos de consumidores.

Al principio, se describen los dos escenarios:

Si todas las instancias de los consumidores tienen el mismo grupo de consumidores, esto funciona igual que una carga de equilibrio de cola tradicional sobre los consumidores.

Si todas las instancias del consumidor tienen diferentes grupos de consumidores, esto funciona como publicar-suscribir y todos los mensajes se transmiten a todos los consumidores.

Entonces, cuantos más grupos de suscriptores tenga, menor será el rendimiento, ya que kafka necesita replicar los mensajes a todos esos grupos y garantizar el orden total.

Por otro lado, cuanto menos grupo y más particiones tenga, más obtendrá al paralistar el procesamiento del mensaje.