Репликация раздела в случае сообщений, отправленных непосредственно в раздел в Kafka

#apache-kafka #kafka-producer-api

#apache-kafka #kafka-producer-api

Вопрос:

Насколько я понимаю, производитель и потребители записывают и считывают в leader broker, содержащий раздел leader. После записи записи в раздел лидера запись реплицируется через раздел-последователь.

Недавно я прочитал, что производитель может явно выполнять запись в определенный раздел. Возможно ли это, и если да, произойдет ли репликация с другим разделом, поскольку он может не быть ведущим разделом.

Ответ №1:

Да, вы можете явно выполнять запись в определенный раздел. У каждого раздела есть узел лидера, а остальные узлы являются последователями. Когда вы выполняете запись в раздел, она записывается на узел, который является лидером для этого раздела, а последующие узлы реплицируют эти данные.

Например, если вы создаете кластер с 3 узлами-посредниками (broker1, broker2, broker3) и, допустим, создаете раздел с 3 разделами (0, 1, 2) и настраиваете его на наличие 2 реплик.

В этом случае каждый посредник будет лидером для одного раздела, а реплики — для двух других. Допустим:

 partition 0 has leader as broker1 and replicas as broker2 and broker3
partition 1 has leader as broker2 and replicas as broker1 and broker3
partition 2 has leader as broker3 and replicas as broker1 and broker2
  

Когда вы записываете в раздел 0, он записывается в его ведущий узел broker1, а затем реплицируется на другие узлы и аналогично для других разделов.

Хотя broker2 является лидером для раздела 1, он является последователем для разделов 0 и 2, и все сообщения, которые необходимо реплицировать из раздела 0 или 2, будут записаны в broker2, поскольку он является лидером только для раздела 1.

Ответ №2:

«Недавно я прочитал, что производитель может явно выполнять запись в определенный раздел. Возможно ли это […] «

Да, это правда. Вы можете определить пользовательский разделитель, реализовав Partitioner и объявив его в конфигурации KafkaProducer partitioner.class

Вот пример пользовательского разделителя в Java:

 public class MyPartitioner implements Partitioner {
  public void configure(Map<String, ?> configs) {}
  public void close() {}

  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();

    if ((keyBytes == null) || (!(key instanceOf String)))
      throw new InvalidRecordException("Record did not have a string Key");

    if (((String) key).equals("myKey"))
       return 0; // This key will always go to Partition 0

    // Other records will go to the rest of the Partitions using a hashing function
    return (Math.abs(Utils.murmur2(keyBytes)) % (numPartitions - 1))   1;
  }
}
  

«[…] и если да, произойдет ли репликация с другим разделом, поскольку он может не быть ведущим разделом?»

Вы смешиваете разделы с репликами. Это две независимые концепции, поскольку разделы распределяют данные темы по нескольким местам для достижения параллелизма, тогда как репликация фактически дублирует данные по всему кластеру для повышения надежности.

Использование пользовательского разделителя по-прежнему гарантирует, что ваш KafkaProducer будет взаимодействовать только с лидером раздела и записывать данные в него.

Помните, что у каждого раздела в теме есть лидер раздела. У вас столько лидеров разделов, сколько разделов в теме.

Комментарии:

1. «Использование пользовательского разделителя по-прежнему гарантирует, что ваш KafkaProducer будет взаимодействовать только с лидером раздела и записывать данные в него».