데이터 유실은 보통 Producer가 메시지를 보냈으나 Broker에 안전하게 저장되지 않았을 떄 발생한다.
acks=all (또는 -1) : 리더 파티션뿐만 아니라 min.insync.replicas에 설정된 모든 복제본이 메시지를 받았는지 확인한다.min.insync.replicas : 메시지가 성공적으로 기록되었다고 간주하기 위한 최소 복제본 수이다.
min.isr이 2라면, 리더를 포함해 최소 2개의 브로커에 데이터가 복제되어야 성공으로 판단한다.NotEnoughReplicas 예외가 발생하여 가용성보다는 데이터 안정성을 택하게 된다.OUTBOX 테이블에 저장(로컬 트랜잭션)네트워크 재시도 등으로 인해 발생할 수 있는 중복은 컨슈머 측에서 처리해야 한다.
enable.idempotence=true 설정을 통해 프로듀서 자체에서 중복 발송을 막을 수 있다.
비즈니스 로직 차원에서의 처리가 가장 확실하다.
min.isr은 데이터 유실 방지의 핵심이다.
| 옵션명 | 설명 | 권장 설정 |
|---|---|---|
replication.factor | 파티션의 전체 복제본 개수 | 보통 3으로 설정 |
min.insync.replicas | acks=all일 떄 응답을 기다릴 최소 ISR 수 | 보통 2로 설정 |
왜 min.isr을 2로 하나요?
Spring Kafka를 사용한다면 DefaultKafkaProducerFactory에서 트랜잭션 매니저를 설정하여 Kafka 트랜잭션을 사용할 수 있다.
// 예시 : Kafka Transactional 설정
@Transactional
fun process(data: String) {
// 1. DB 로직 수행
repository.save(Entity(data))
// 2. Kafka 메시지 발행
kafkaTemplate.send("topic", data)
}
이 방식은 producer.beginTransaction()과 commitTransaction()을 사용하여, DB와 Kafka로의 전송이 원자적으로 처리되도록 한다. (다만, 성능 오버헤드가 있으므로 데이터 중요도에 따라 선택해야 한다)