0Pricing
Advanced Spring Boot 4: Event-Driven Architecture (Kafka) · レッスン

冪等なプロデューサーとコンシューマー

メッセージが再処理される場合でも状態の一貫性を保てるよう、冪等なプロデューサーとコンシューマーを設計する重要性を理解します。

「冪等なプロデューサーとコンシューマー」はCoddyKit上の無料Advanced Spring Boot 4: Event-Driven Architecture (Kafka)レッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAdvanced Spring Boot 4: Event-Driven Architecture (Kafka)学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Advanced Spring Boot 4: Event-Driven Architecture (Kafka)コースには全4レッスンが含まれています。

このレッスンの一部はまだ翻訳されておらず、英語で表示されています。

What is Idempotence?

Imagine pressing a light switch. If you press it once, the light turns on. If you press it again, the light stays on – it doesn't get 'more on'. This is idempotence!

An operation is idempotent if performing it multiple times produces the same result as performing it once. It's about the final state, not how many times you tried to get there.

Why Idempotence in Messaging?

In distributed systems like those using Kafka, messages can sometimes be delivered more than once. This can happen due to network issues, consumer crashes, or rebalances.

If your application isn't designed to handle these duplicates, reprocessing the same message multiple times could lead to incorrect data or undesirable side effects.

Kafka's Idempotent Producers

Good news! Kafka provides built-in support for idempotent producers. This means when you send a message, Kafka guarantees that it will be written to the topic log exactly once, even if the producer retries sending it due to transient failures.

This prevents duplicate messages from being stored in Kafka itself.

How Kafka Idempotence Works

Kafka achieves producer idempotence by assigning a unique Producer ID (PID) to each producer session and a monotonically increasing sequence number to each message batch sent by that producer.

Kafka brokers use these IDs and sequence numbers to detect and discard any duplicate message batches before they are written to the log.

Enabling Idempotent Producers

In Spring Boot, enabling an idempotent Kafka producer is straightforward. You just need to set a specific property in your application.properties or application.yml.

  • spring.kafka.producer.properties.enable.idempotence=true

Setting this property also implicitly configures other necessary producer settings, such as acks=all and retries.

Idempotent Producer Example

Try running this simple Spring Boot application. It sends a message to a Kafka topic with idempotence enabled. Notice the configuration comments.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import java.util.UUID;

@SpringBootApplication
public class IdempotentProducerApp {

  public static void main(String[] args) {
    SpringApplication.run(IdempotentProducerApp.class, args);
  }

  @Bean
  public CommandLineRunner runner(
    KafkaTemplate<String, String> kafkaTemplate) {
    return args -> {
      String messageKey = UUID.randomUUID().toString();
      String messageValue = "Hello from Idempotent Producer!";
      System.out.println("Sending message with key: " 
                         + messageKey);
      kafkaTemplate.send("my-idempotent-topic", 
                         messageKey, messageValue)
        .addCallback(
          result -> System.out.println(
            "Message sent successfully!"),
          ex -> System.err.println(
            "Failed to send: " + ex.getMessage())
        );
    };
  }
}
// Add to application.properties:
// spring.kafka.producer.bootstrap-servers=localhost:9092
// spring.kafka.producer.key-serializer=
//   org.apache.kafka.common.serialization.StringSerializer
// spring.kafka.producer.value-serializer=
//   org.apache.kafka.common.serialization.StringSerializer
// spring.kafka.producer.properties.enable.idempotence=true

Idempotent Consumers

While Kafka helps producers avoid sending duplicates to the log, it doesn't guarantee that consumers will process messages exactly once. Consumers might read the same message multiple times.

Therefore, idempotent consumer logic is crucial. This means your application code must ensure that processing a message multiple times has no unintended side effects on your system's state.

Strategies for Idempotent Consumers

Here are common approaches to make your consumers idempotent:

  • Unique ID Tracking: Store a unique identifier (like Kafka's topic-partition-offset or a business ID from the message) in a persistent store. Check this store before processing.
  • State Comparison: Before applying an update, compare the incoming message's data with the current state in your system. Only apply if the state needs changing.
  • Business Idempotence: Design your business operations to be naturally idempotent. For example, 'set user status to X' is idempotent, 'increment user balance by Y' is not.

Consumer Idempotence Example

This Spring Boot example demonstrates a basic idempotent consumer using a set to track processed records. In a real application, this would be a persistent store like a database or Redis.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import java.util.HashSet;
import java.util.Set;

@SpringBootApplication
public class IdempotentConsumerApp {

  public static void main(String[] args) {
    SpringApplication.run(IdempotentConsumerApp.class, args);
  }

  @Component
  public static class MyKafkaListener {
    // In a real app, this would be a persistent store (DB, Redis)
    private final Set<String> processedRecordIds = new HashSet<>();

    @KafkaListener(topics = "my-idempotent-topic", 
                   groupId = "idempotent-group")
    public void listen(ConsumerRecord<String, String> record) {
      // Unique ID for the record (topic-partition-offset)
      String recordId = record.topic() + "-" + record.partition()
                        + "-" + record.offset();

      if (processedRecordIds.contains(recordId)) {
        System.out.println("Duplicate record received (ID: " 
                           + recordId + "). Skipping processing.");
        return;
      }

      // Simulate processing the message
      System.out.println("Processing record ID: " + recordId 
                         + ", Key: " + record.key() 
                         + ", Value: " + record.value());
      // Add to processed set AFTER successful processing
      processedRecordIds.add(recordId);

      // In a real scenario, processing might involve DB updates
      // and 'add' would happen as part of a transaction.
    }
  }
}
// Add to application.properties:
// spring.kafka.consumer.bootstrap-servers=localhost:9092
// spring.kafka.consumer.key-deserializer=
//   org.apache.kafka.common.serialization.StringDeserializer
// spring.kafka.consumer.value-deserializer=
//   org.apache.kafka.common.serialization.StringDeserializer
// spring.kafka.consumer.group-id=idempotent-group
// spring.kafka.consumer.auto-offset-reset=earliest

Quick Check: Idempotence

Test your understanding of idempotent operations in messaging.

Recap & Next Steps

Great job! In this lesson, you've learned about the vital concept of idempotence in event-driven systems.

  • You understand why idempotence is critical for maintaining consistent state when messages might be reprocessed.
  • You saw how Kafka's built-in idempotent producers prevent duplicate messages from entering the topic.
  • You explored strategies for building idempotent consumers, ensuring your application handles duplicate messages gracefully.

Mastering idempotence is a key step towards building robust and reliable Kafka applications!

よくある質問

「冪等なプロデューサーとコンシューマー」レッスンは無料ですか?

はい。「冪等なプロデューサーとコンシューマー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Advanced Spring Boot 4: Event-Driven Architecture (Kafka)コースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Advanced Spring Boot 4: Event-Driven Architecture (Kafka)コースには全4レッスンが含まれています。

「冪等なプロデューサーとコンシューマー」で何を学びますか?

メッセージが再処理される場合でも状態の一貫性を保てるよう、冪等なプロデューサーとコンシューマーを設計する重要性を理解します。 ブラウザで直接実行するハンズオンコードでAdvanced Spring Boot 4: Event-Driven Architecture (Kafka)を演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Advanced Spring Boot 4: Event-Driven Architecture (Kafka)を始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAdvanced Spring Boot 4: Event-Driven Architecture (Kafka)は初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「冪等なプロデューサーとコンシューマー」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAdvanced Spring Boot 4: Event-Driven Architecture (Kafka)レッスンでコードを書いて実行できますか?

はい。すべてのAdvanced Spring Boot 4: Event-Driven Architecture (Kafka)レッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Kafkaのパフォーマンスチューニング
  2. 冪等なプロデューサーとコンシューマー
  3. Spring Boot Kafkaアプリケーションのクラウドへのデプロイ
  4. キャパシティプランニング:パーティションとレプリケーション
← Advanced Spring Boot 4: Event-Driven Architecture (Kafka)に戻る