백엔드 면접 용어 사전
메시지 큐compaction · cleanup.policy

로그 컴팩션

같은 키의 최신 값만 남기는 Kafka의 정리 방식. 토픽을 이벤트 기록이 아니라 현재 상태 스냅샷으로 만든다.

Kafka 토픽에서 같은 키의 가장 최신 값만 남기고 과거 값을 정리하는 방식. cleanup.policy=compact로 켠다.

기본 방식(delete)과의 차이 — 지우는 기준

  • cleanup.policy=delete — 기준은 나이·크기

    • retention.ms(기본 7일)를 넘긴 세그먼트 파일을 통째로 삭제
  • cleanup.policy=compact — 기준은 키

    • 같은 키의 옛 값만 골라 제거. 나이와 무관

동작

컴팩션 전:  (u1,"서울") (u2,"부산") (u1,"대전") (u3,"광주") (u1,"제주")
                 ↓  같은 키의 옛 값 제거
컴팩션 후:  (u2,"부산") (u3,"광주") (u1,"제주")

중요한 성질이 하나 있다 — 오프셋 번호는 그대로 유지된다. 즉 컴팩션 후 오프셋이 촘촘하지 않고 군데군데 비는데, 컨슈머는 원래 "다음 오프셋으로"가 아니라 "다음에 존재하는 레코드로" 읽으므로 문제가 없다.

무엇에 쓰나 — 토픽의 성격이 바뀐다

컴팩션 토픽은 "무슨 일이 있었나(이벤트 기록)"가 아니라 "지금 어떤 상태인가(스냅샷)" 를 표현한다. 처음부터 끝까지 다 읽으면 모든 키의 최신 상태가 복원되기 때문이다.

  • 서비스가 뜰 때 캐시를 채우는 용도(캐시 워밍)
  • 설정·기준정보 배포
  • Kafka 자신도 쓴다 — __consumer_offsets가 컴팩션 토픽이다. 필요한 건 "이 그룹의 현재 오프셋"이지 그 변경 이력이 아니니까

두 가지 전제

① 키가 없으면 컴팩션할 수 없다. 무엇의 최신인지 판단할 근거가 없다. 컴팩션 토픽에 보낼 메시지는 반드시 키를 가져야 한다.

② 삭제는 툼스톤으로 표현한다. 키는 있고 값이 null 인 메시지를 툼스톤(tombstone, 묘비) 이라 부른다. 컴팩션이 이걸 만나면 그 키의 모든 값을 지운다.

producer.send(new ProducerRecord<>("users", "u1", null));   // u1 삭제 표시

툼스톤 자체도 영원히 남지 않는다. 컨슈머들이 "이 키가 지워졌다"를 볼 시간을 준 뒤 delete.retention.ms 가 지나면 정리된다. 개인정보 삭제 요구(GDPR 등)가 이 방식으로 처리된다.

둘을 함께 쓰기

  • cleanup.policy=compact,delete
  • 먼저 키별로 컴팩션하고, 그다음 리텐션으로 오래된 것을 버린다

면접 함정

  • "컴팩션을 켜면 중복 메시지가 사라진다"같은 키의 옛 값을 정리하는 것이지 중복 제거가 아니다. 중복은 여전히 컨슈머 멱등성으로 푼다.
  • "컴팩션 토픽은 재처리에 좋다" → 반대다. 중간 이력이 사라지므로 이벤트 재생에는 쓸 수 없다. 재생이 목적이면 delete + 충분한 리텐션이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 메시지 큐·비동기 — Kafka/RabbitMQ·EOS·순서·outbox