카프카가 일반적인 메시지 큐와 가장 차별화되는 지점이 바로 이 '데이터 보관'에 있습니다. "전달하면 끝"이 아니라 "기록하고 보관한다"는 철학 때문이죠. 하지만 무한정 데이터를 쌓아둘 순 없으니 효율적으로 비워내는 기술이 필요합니다.
이것을 결정하는 것이 바로 cleanup.policy입니다. 단순히 데이터를 삭제하는 법부터 데이터의 '최종 상태'만 남기는 고급 기술인 로그 컴팩션(Log Compaction)까지 낱낱이 파헤쳐 보겠습니다!

🧹 카프카의 데이터 청소 정책: cleanup.policy
카프카의 토픽은 기본적으로 세그먼트(Segment)라는 작은 파일 단위로 쪼개져 디스크에 저장됩니다. 청소는 이 세그먼트 단위로 이루어지며, 정책은 크게 두 가지입니다.
1. Delete 정책 (삭제: 가장 일반적인 방식)
대부분의 토픽이 사용하는 기본 정책입니다. 특정 기준을 넘어서면 오래된 데이터부터 가차 없이 지워버립니다.
- 보관 기간 기준 (
retention.ms): "일주일(7일)이 지난 데이터는 지워라." 가장 흔한 설정입니다. - 보관 크기 기준 (
retention.bytes): "토픽의 크기가 100GB를 넘으면 가장 오래된 것부터 지워라." 디스크 용량이 아슬아슬할 때 유용합니다. - 작동 방식: 카프카는 백그라운드에서 주기적으로 체크하다가, 활성화된(Active) 세그먼트가 아닌 '닫힌' 세그먼트 중 기준을 초과한 파일을 삭제합니다.
2. Compact 정책 (압축: 최종 상태 유지 방식)
이것이 바로 주목하셔야 할 카프카의 진수입니다. 데이터를 지우는 게 아니라, 동일한 메시지 키(Key)에 대해 가장 최신 값(Value)만 남기고 나머지는 정리하는 방식입니다.
- 핵심 원리: "과거의 이력보다는 현재의 최종 상태가 중요하다"는 로직입니다.
- 작동 방식: 1. 카프카 브로커는 백그라운드에서 Log Cleaner 스레드를 돌립니다.
- 동일한 키를 가진 메시지들을 찾아냅니다. (예: 주식 종목 '삼성전자'에 대한 여러 시간대의 가격 데이터)
- 가장 최근의 값만 남기고 과거의 중복된 키 데이터는 삭제합니다.
📈 'Compact' 정책이 왜 주식 종목 관리에 유리할까요?
주식 종목 데이터를 예로 들어보겠습니다.
- 상황: 전 종목의 현재가를 실시간으로 카프카에 넣고 있습니다. '삼성전자'라는 키값으로 1초에 한 번씩 데이터가 들어오죠.
- Delete 정책 사용 시: 일주일치 데이터를 보관하면 삼성전자에 대한 과거 604,800개의 가격 이력이 다 남아있습니다. 특정 종목의 현재가만 알고 싶은 컨슈머는 이 60만 개를 다 읽어야 마지막 현재가를 알 수 있습니다. 비효율적이죠.
- Compact 정책 사용 시: 컴팩션이 일어나면 삼성전자 키에 대해 마지막으로 들어온 가격 데이터만 남습니다. 새로운 컨슈머가 붙어서 데이터를 읽으면, 과거 이력을 뒤질 필요 없이 즉시 모든 종목의 '최신 상태(State)'를 복구할 수 있습니다.
💡 Deep Point: 주식 종목의 상장 폐지나 종목 삭제는 어떻게 처리할까요?
카프카에서는 해당 키값에 대해 Value를null로 해서 메시지를 보냅니다. 이를 툼스톤(Tombstone) 메시지라고 부릅니다. 컴팩션 스레드가 돌다가 이 툼스톤을 발견하면 "아, 이 키는 삭제됐구나"라고 판단하고 일정 시간 뒤에 해당 데이터를 완전히 지워버립니다.
🛠️ 세그먼트(Segment): 청소의 단위
카프카는 파일 하나에 모든 데이터를 다 넣지 않습니다.
- 세그먼트 분할: 설정된 크기(
segment.bytes, 기본 1GB)나 시간(segment.ms)이 되면 현재 쓰던 파일을 닫고 새 파일을 만듭니다. - 액티브 세그먼트(Active Segment): 현재 데이터를 쓰고 있는 파일입니다. 이 파일은 절대로 삭제되거나 컴팩션되지 않습니다.
- 청소 대상: 닫힌(Closed) 세그먼트들만이 삭제나 압축의 대상이 됩니다.
📊 Delete vs Compact 한눈에 비교
| 비교 항목 | Delete (삭제) | Compact (압축) |
|---|---|---|
| 핵심 철학 | 오래된 정보는 쓸모없다. | 최종 상태가 가장 중요하다. |
| 기준 | 시간(Retention) 또는 용량 | 메시지의 키(Key) 중복 여부 |
| 데이터 유실 | 오래된 데이터는 완전히 사라짐 | 키별 마지막 값은 영구 보관 가능 |
| 주요 용도 | 로그 분석, 일반적인 이벤트 흐름 | DB 미러링, 설정값 관리, 상태 저장소 복구 |
| DB 비유 | 로그 파일 (Log) | 테이블의 현재 상태 (Table) |
💡운영 팁: "디스크가 꽉 찼을 때의 응급처치"
만약 실무에서 디스크 용량이 90%를 넘었다는 알람이 오면 당황하지 마시고 이 순서대로 체크하세요!
- 보관 주기 확인:
retention.ms가 너무 길게 설정되어 있지 않은지 확인하고, 필요하다면 값을 줄여서 즉시 세그먼트 삭제를 유도합니다. - 세그먼트 크기 확인:
segment.bytes가 너무 크면, 아직 파일을 다 못 채워서 'Active' 상태로 남아있느라 삭제가 안 될 수 있습니다. 이 크기를 줄여서 파일을 빨리 닫게(Close) 만들어야 청소가 시작됩니다. - 컴팩션 지연 확인: Compact 정책을 쓰는데 용량이 안 줄어든다면,
min.cleanable.dirty.ratio설정을 확인하세요. 지저분한 데이터(업데이트된 데이터)가 일정 비율 쌓여야 컴팩션이 시작되는데, 이 비율이 너무 높으면 청소를 안 하고 버티고 있을 수 있습니다.
'1. 개발 > 1.4. 데이터 분석' 카테고리의 다른 글
| Kafka - '최소 한 번(At-least-once)' vs '딱 한 번(Exactly-once)' (0) | 2026.02.06 |
|---|---|
| Kafka - 성능 모니터링의 핵심 지표인 '컨슈머 랙(Consumer Lag)' (0) | 2026.02.06 |
| Kafka는 어떻게 부하를 분산할까? (Consumer Group) (1) | 2026.02.05 |
| Kafka - ack 옵션(0, 1, all) (0) | 2026.02.05 |
| Kafka - 데이터 유실을 막기 위한 'ISR(In-Sync Replicas)' 개념 (0) | 2026.02.05 |