Apache Kafka – популярная распределенная платформа потоковой передачи, которая широко используется для создания конвейеров данных в реальном времени и приложений потоковой передачи. Одной из ключевых причин популярности Kafka является его способность предоставлять надежные гарантии доставки сообщений. В этой статье мы рассмотрим гарантии, предоставляемые Kafka, и обсудим различные методы с примерами кода для достижения этих гарантий.
- Доставка сообщений «хотя бы один раз».
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", производитель ожидает подтверждения от всех синхронизированных реплик, прежде чем считать сообщение успешно отправленным.
- Доставка сообщений «точно один раз».
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", производитель гарантирует, что повторяющиеся сообщения не будут создаваться, даже если происходят повторные попытки.
- Идемпотентный производитель:
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.