Apache Kafka, modern olay odaklı mimarilerin omurgasıdır, ancak bu gücü karmaşıklıkla birlikte gelir. Geliştiriciler için en zorlu iki yön, tüketici grubu yeniden dengelemeyi yönetmek ve tam bir kez işleme semantiğini sağlamaktır. Dağıtık kümelemede bu sorunlar, doğru şekilde ele alınmazsa mesaj çoğaltılmasına, veri kaybına veya önemli kesintilere yol açabilir. Bu kılavuz, bu sorunları azaltmak ve Kafka ekosisteminizi optimize etmek için gelişmiş stratejileri ele alır.
Tüketici Grubu Yeniden Dengelemeyi Anlama
Tüketiciler bir gruba katıldığında veya gruptan ayrıldığında, ya da konular oluşturulduğunda veya silindiğinde Kafka bir yeniden dengeleme tetikler. Bu süreç sırasında, bölümlerin tüketicilere atanması yeniden hesaplanır. Yük dengelemesi için gerekli olsa da, yeniden dengelemeler, tüm tüketicilerin yeni atamaları beklemek için tüketimi duraklattığı "dünyayı durduran" senaryolarına neden olabilir.
Geleneksel yeniden dengeleme protokolleri (klasik protokol gibi), tüketiciler ve koordinatör arasında çoklu gidiş-dönüş gerektirir. Bu yükü azaltmak için Kafka, Artımlı İşbirlikçi Yeniden Dengeleme protokolünü tanıttı. Bu yaklaşım, tüketicilerin taşınmayan bölümler için mevcut atamalarını korumasına olanak tanır ve bu da duraklama süresini önemli ölçüde azaltır.
Yeniden Dengeleme Gecikmesini Optimize Etme
Yeniden dengelemelerin etkisini daha da azaltmak için aşağıdaki tüketici yapılandırmalarını ayarlamayı düşünün:
max.poll.interval.ms: Tüketicinin gruptan atılmasını önlemek için uygulamanızın mesajları bu aralıktan daha hızlı işleyebildiğinden emin olun.heartbeat.interval.ms: Arızaları daha hızlı tespit etmek için bunusession.timeout.msdeğerine göre düşük tutun, ancak ağ dalgalanmalarının gereksiz yeniden dengelemeleri tetiklemeyecek kadar düşük tutmayın.
Properties props = new Properties();
props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-advanced-group");
props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, 300000); // 5 dakika
props.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, 3000); // 3 saniye
props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 45000); // 45 saniye
props.put(ConsumerConfig.REBALANCE_TIMEOUT_MS_CONFIG, 600000); // 10 dakika
props.put("partition.assignment.strategy", "org.apache.kafka.clients.consumer.CooperativeStickyAssignor");
Tam Bir Kez Semantiğini Sağlama
Tam bir kez semantiği (EOS), arızalara rağmen her mesajın tam olarak bir kez işlendiğini garanti eder. Kafka bunu, idempotent üreticiler ve işlem API'lerinin bir kombinasyonu ile sağlar.
Idempotent Üreticiler
Idempotence'ı etkinleştirmek, üretici yeniden denemelerinden kaynaklanan mükerrer mesajları önler. Üretici yapılandırmanızda enable.idempotence=true olarak ayarlayın. Dayanıklılık için bu, broker tarafında acks=all ve min.insync.replicas=2 (veya daha fazla) gerektirir.
İşlemsel Mesajlar
Birden fazla konuya atomik olarak üretim yapmanız veya tüketici ofsetlerini üretim ve taahhüt etmeniz gereken karmaşık iş akışları için Kafka işlemlerini kullanın. Bunun için her üretici örneği için bir işlem kimliği (transactional ID) gerekir.
Properties producerProps = new Properties();
producerProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9092");
producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
producerProps.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
producerProps.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG, "tx-id-001");
KafkaProducer producer = new KafkaProducer<>(producerProps);
producer.initTransactions();
try {
producer.beginTransaction();
// Birden fazla konuya atomik olarak üretim yap
producer.send(new ProducerRecord<>("topic-a", "key1", "value1"));
producer.send(new ProducerRecord<>("topic-b", "key2", "value2"));
// Tüketici ofsetlerini aynı işlem içinde taahhüt et
consumer.commitSync(Map.of(topicPartition, new OffsetAndMetadata(offset)));
producer.commitTransaction();
} catch (Exception e) {
producer.abortTransaction();
}
Dağıtık Kümeleler İçin Pratik Düşünceler
Büyük kümelelerde EOS'u uygularken şunların farkında olun:
1. İşlem Boyutu Sınırları: İşlemleri küçük tutun. Büyük işlemler zaman aşımı riskini artırır ve koordinatörde önemli miktarda bellek gerektirir. 2. Bölüm Anahtarı Tutarlılığı: Sıralamayı korumak ve idempotence'ı basitleştirmek için aynı anahtarın her zaman aynı bölüme eşlendiğinden emin olun. 3. İzleme: İşlemsel işlemedeki darboğazları tespit etmek içinkafka:transaction-coordinator metriklerini izleyin.
Sonuç
Tüketici grubu yeniden dengelemesini ve tam bir kez semantiğini ustalaşmak, güvenilir ve yüksek performanslı Kafka uygulamaları oluşturmak için gereklidir. İşbirlikçi yeniden dengelemeyi ve işlemsel API'leri kullanarak kesinti süresini en aza indirebilir ve veri bütünlüğünü sağlayabilirsiniz. Yapılandırmalarınızı her zaman belirli iş yükünüze göre ayarlayın ve sorunlar uygulamanızı etkilemeden önce kümeyi metriklerini izleyin. Bu gelişmiş stratejilerle, dağıtık sistemlerinizde Kafka'nın tam potansiyelini ortaya çıkarabilirsiniz.