3 estrategias de partición cuando Kafka genera mensajes

Resumen: cuando KafkaProducer envía un mensaje, debe especificar a qué partición enviar, entonces, ¿cuáles son las estrategias de partición?

Este artículo se comparte desde Huawei Cloud Community " Estrategia de asignación de particiones de Kafka Producer 3 ", autor: tienda de comestibles de Shi Zhenzhen.

Cuando KafkaProducer envía un mensaje, debe especificar a qué partición enviar, entonces, ¿cuáles son las estrategias de partición? Echemos un vistazo hoy

Configuración usando la estrategia de partición:

1. Estrategia de partición predeterminada de DefaultPartitioner

Nombre completo de la clase de ruta: org.apache.kafka.clients.producer.internals.DefaultPartitioner

  • Si se especifica una partición en el mensaje, se utiliza
  • Si no se especifica ninguna partición pero existe la clave, la cantidad de particiones es módulo la cantidad de particiones utilizando el algoritmo hash murmur2 basado en la clave serializada.
  • Si no existe ninguna partición o clave, se usa la estrategia de particionamiento fijo , consulte KIP-480 para el particionamiento fijo.

Partición pegajosa

¿Por qué existe el concepto de particiones pegajosas?

Primero, especificamos que cuando el Productor envía un mensaje, colocará el mensaje en un ProducerBatch, que puede contener varios mensajes, y luego empaquetará el Lote para enviarlo. Para esto, consulte mi artículo anterior que ilustra el modelo de almacenamiento en caché de mensajes de Kafka Producer.

La ventaja de esto es que puede mejorar el rendimiento y reducir el número de solicitudes.

Pero hay un problema, porque el mensaje se envía, debe enviarse cuando uno de sus lotes está lleno o se acabó el tiempo de linger.ms. Si se producen menos mensajes, será difícil llenar el Lote, lo que significa una mayor latencia.

En el envío del mensaje anterior, el mensaje se sondeó a cada partición. Hay pocos mensajes. Si otorga una asignación transversal a todas las particiones, es difícil que cada ProducerBatch cumpla con las condiciones.

Entonces, si lleno un ProducerBatch primero, ¿puedo asignar otras particiones para reducir este retraso?

Para más detalles, por favor vea la imagen de abajo

La premisa de esta imagen es:

El Tema 1 tiene 3 particiones. En este momento, se envían 9 mensajes sin clave al Tema 1, y la suma de estos 9 mensajes no supera el tamaño del lote.

Luego, el método de asignación anterior y el método de asignación de la partición adhesiva son los siguientes

Se puede ver que después de usar particiones adhesivas , al menos un lote se llena para enviar y luego se llena otro lote. No será como antes. Aunque se distribuye uniformemente, un lote no está lleno y no se puede enviar de inmediato. ¿Esto no aumenta la demora (solo se puede enviar cuando se acabe el tiempo de linger.ms)?

Concentrarse en:

  1. Después de enviar un lote, se debe seleccionar una nueva partición adhesiva
    ①. La partición disponible es menor que 1; luego, la lógica de seleccionar particiones es seleccionar aleatoriamente entre todas las particiones .
    ② Partición disponible = 1. A continuación, seleccione esta partición directamente.
    ③ Partición disponible > 1, luego seleccione aleatoriamente entre todas las particiones disponibles .
  2. Cuando se selecciona la siguiente partición fija, no se asigna de acuerdo con el principio del promedio de partición. Pero el principio de aleatoriedad (por supuesto, no es lo mismo que la última partición)

Por ejemplo, el lote recién enviado es la partición 1. Cuando el lote está lleno, se pueden enviar mensajes nuevos a 2 o 3 después del envío. Si el lote seleccionado es 2, después de que el lote de 2 esté lleno, el siguiente lote seleccionado aún sea ​​Probablemente 1, en lugar de decir eso para promediar, elija 3 particiones.

2. Estrategia de partición adhesiva pura UniformStickyPartitioner

Nombre de clase de ruta completa: org.apache.kafka.clients.producer.internals.UniformStickyPartitioner

La única diferencia entre él y la estrategia de partición DefaultPartitioner es. 

Si DefaultPartitionerd tiene una clave, entonces determina la partición de acuerdo con la clave. En este momento, la partición permanente no se usará.
UniformStickyPartitioner usará la partición permanente para asignarla independientemente de si tiene una clave o no.

3. Estrategia de partición RoundRobinPartitioner

Nombre completo de la clase de ruta: org.apache.kafka.clients.producer.internals.RoundRobinPartitioner

  • Si se especifica una partición en el mensaje, se utiliza
  • Distribuya los mensajes uniformemente a cada partición.
  • no tiene nada que ver con la llave
    @Override
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        int numPartitions = partitions.size();
        int nextValue = nextValue(topic);
        List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
        if (!availablePartitions.isEmpty()) {
            int part = Utils.toPositive(nextValue) % availablePartitions.size();
            return availablePartitions.get(part).partition();
        } else {
            // no partitions are available, give a non-available partition
            return Utils.toPositive(nextValue) % numPartitions;
        }
    }

Lo anterior es el código específico. Hay un lugar para prestar atención;

  1. Cuando la partición disponible es 0, se recorren todas las particiones.
  2. Cuando hay particiones disponibles, se recorren todas las particiones disponibles.

 

Haga clic en Seguir para conocer las nuevas tecnologías de HUAWEI CLOUD por primera vez~

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4526289/blog/5517563
Recomendado
Clasificación