← 학습 카테고리

Learn

Kafka

84개 모듈 · 현재 77번째

Kafka 모듈 77/84 kafka-learn-77

sendOffsetsToTransaction — 오프셋 커밋을 트랜잭션 안에 직접 끼워 넣는다

Kafka sendOffsetsToTransaction 및 Consumer position()/committed() 공식 문서 종합 (웹 리서치, 2026) — Apache Kafka KIP-98(Exactly Once Delivery and Transactional Messaging), Apache Kafka 공식 Javadoc KafkaConsumer Apache Kafka KIP-98: Exactly Once Delivery and Transactional Messaging

이 모듈을 다 읽으면

  • kafka-learn-49의 Kafka Streams EOS(프레임워크 자동 처리)와 이 모듈의 수동 패턴이 원리는 같고 구현 층위만 다르다는 것을 설명할 수 있다
  • read_committed 격리 수준의 컨슈머와 트랜잭셔널 프로듀서를 조합해 consume-transform-produce 루프를 짜는 표준 패턴을 설명할 수 있다

kafka-learn-49에서 다룬 Kafka Streams의 exactly_once_v2(프레임워크가 오프셋 커밋+상태갱신+출력쓰기를 자동으로 하나의 트랜잭션에 묶음)를 전제로, 일반 컨슈머·프로듀서 클라이언트만으로 같은 효과를 직접 구현하는 저수준 패턴을 정리한다.

왜 필요한가 — '읽기'와 '쓰기'가 서로 다른 시스템(오프셋 저장 vs 출력 토픽)이다

일반 컨슈머·프로듀서로 read-process-write를 직접 짜면, '입력 오프셋 커밋'과 '출력 레코드 쓰기'가 원자적으로 묶이지 않는 문제가 있다 — 둘 중 하나만 성공하고 다른 하나가 실패하면(예: 출력은 썼는데 오프셋 커밋 전에 죽으면) 재시작 시 그 레코드를 중복 처리하게 된다. sendOffsetsToTransaction()은 이 문제를 해결한다 — 지정한 오프셋 목록을 컨슈머 그룹 코디네이터에 보내면서, 그 오프셋들을 현재 진행 중인 트랜잭션의 일부로 표시한다. 그 트랜잭션이 커밋에 성공해야만 이 오프셋들도 비로소 커밋된 것으로 간주된다.

핵심 포인트

  • 일반 컨슈머+프로듀서로 직접 짠 read-process-write는 '입력 오프셋 커밋'과 '출력 쓰기'가 원자적으로 안 묶여 중복 처리 위험
  • sendOffsetsToTransaction()으로 오프셋을 현재 트랜잭션의 일부로 표시 — 트랜잭션이 커밋돼야만 오프셋도 비로소 커밋된 것으로 간주

표준 패턴 — read_committed 컨슈머 + 트랜잭셔널 프로듀서

표준적인 exactly-once 사용 패턴은 다음과 같다 — 컨슈머는 isolation.level=read_committed로 설정(kafka-learn-35에서 다룬 것처럼 커밋된 트랜잭션의 레코드만 보이게 함)하고, 프로듀서는 고유하고 안정적인 transactional.id를 설정한다. 루프 안에서는 poll()로 레코드를 받고, beginTransaction()으로 트랜잭션을 시작하고, 변환한 결과를 출력 토픽에 send()하고, sendOffsetsToTransaction()으로 입력 오프셋을 그 트랜잭션에 포함시킨 뒤, commitTransaction()으로 마무리한다. 이 commitTransaction()이 성공해야만 출력 메시지도 보이고 오프셋도 커밋된 것으로 확정된다 — kafka-learn-49의 Kafka Streams EOS가 프레임워크 차원에서 자동으로 해주는 걸, 여기서는 개발자가 직접 이 순서대로 조립하는 것이다.

핵심 포인트

  • 패턴: 컨슈머(isolation.level=read_committed)+프로듀서(고유 transactional.id) → poll()→beginTransaction()→출력 send()→sendOffsetsToTransaction(입력 오프셋)→commitTransaction()
  • commitTransaction() 성공 시에만 출력 메시지 가시화+오프셋 커밋 확정 — kafka-learn-49의 Streams EOS를 개발자가 직접 저수준으로 조립한 것