Комплексное руководство по гарантиям, предоставляемым Kafka

Apache Kafka – популярная распределенная платформа потоковой передачи, которая широко используется для создания конвейеров данных в реальном времени и приложений потоковой передачи. Одной из ключевых причин популярности Kafka является его способность предоставлять надежные гарантии доставки сообщений. В этой статье мы рассмотрим гарантии, предоставляемые Kafka, и обсудим различные методы с примерами кода для достижения этих гарантий.

  1. Доставка сообщений «хотя бы один раз».
    Kafka гарантирует, что сообщения будут доставлены хотя бы один раз предполагаемым потребителям. Это означает, что даже в случае сбоя потребителя или временных проблем с сетью Kafka гарантирует, что сообщения не будут потеряны. Чтобы добиться хотя бы однократной доставки, вы можете использовать следующие методы:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all");
Producer<String, String> producer = new KafkaProducer<>(props);
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");
try {
    RecordMetadata metadata = producer.send(record).get();
    System.out.println("Message sent to partition " + metadata.partition() + " at offset " + metadata.offset());
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    producer.close();
}

Установив для конфигурации "acks"значение "all", производитель ожидает подтверждения от всех синхронизированных реплик, прежде чем считать сообщение успешно отправленным.

  1. Доставка сообщений «точно один раз».
    Kafka также поддерживает семантику «точно один раз», которая гарантирует, что сообщения доставляются ровно один раз, без каких-либо дубликатов. Достижение однократной доставки требует координации между производителем и потребителем. Вот пример того, как добиться однократной доставки с помощью Kafka Streams:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all");
props.put("enable.idempotence", "true");
Producer<String, String> producer = new KafkaProducer<>(props);
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");
try {
    RecordMetadata metadata = producer.send(record).get();
    System.out.println("Message sent to partition " + metadata.partition() + " at offset " + metadata.offset());
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    producer.close();
}

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

  1. Идемпотентный производитель:
    Kafka предоставляет идемпотентный производитель, который гарантирует, что дублирующиеся сообщения не будут создаваться даже в случае повторных попыток. Вот пример того, как создать идемпотентного производителя:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all");
props.put("enable.idempotence", "true");
Producer<String, String> producer = new KafkaProducer<>(props);
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");
try {
    RecordMetadata metadata = producer.send(record).get();
    System.out.println("Message sent to partition " + metadata.partition() + " at offset " + metadata.offset());
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    producer.close();
}

Благодаря включению идемпотентности дублирование сообщений предотвращается, что обеспечивает дополнительный уровень надежности.

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