Log Retention 정책

Kafka는 디스크 공간을 관리하기 위해 오래된 메시지를 자동으로 삭제하는 Retention 정책을 제공합니다.

Retention 개요

기본 개념

┌─────────────────────────────────────────────────────────────────┐
│                      Log Retention                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Partition Log:                                                 │
│  ┌────────┬────────┬────────┬────────┬────────┬────────┐       │
│  │Segment │Segment │Segment │Segment │Segment │Segment │       │
│  │   0    │   1    │   2    │   3    │   4    │   5    │       │
│  │ (old)  │        │        │        │        │(active)│       │
│  └────────┴────────┴────────┴────────┴────────┴────────┘       │
│      ↑                                                          │
│   삭제 대상                                                      │
│   (retention 조건 충족)                                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Retention 정책 종류

정책기준설정
시간 기반메시지 생성 후 경과 시간log.retention.ms
크기 기반파티션 로그 총 크기log.retention.bytes
혼합시간 또는 크기 중 먼저 도달둘 다 설정

시간 기반 Retention

설정

# Broker 레벨 (기본값: 7일)
log.retention.hours = 168
# 또는
log.retention.minutes = 10080
# 또는
log.retention.ms = 604800000
 
# 우선순위: ms > minutes > hours

Topic 레벨 설정

# 토픽 생성 시
kafka-topics.sh --create \
    --topic my-topic \
    --bootstrap-server localhost:9092 \
    --config retention.ms=86400000  # 1일
 
# 기존 토픽 수정
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name my-topic \
    --bootstrap-server localhost:9092 \
    --add-config retention.ms=86400000

동작 방식

Timeline:
                    retention.ms = 3일
    ├─────────────────────────────────────┤

Day 1        Day 2        Day 3        Day 4        Day 5
  │            │            │            │            │
  ▼            ▼            ▼            ▼            ▼
┌────┐      ┌────┐      ┌────┐      ┌────┐      ┌────┐
│Seg0│      │Seg1│      │Seg2│      │Seg3│      │Seg4│
└────┘      └────┘      └────┘      └────┘      └────┘

Day 5 시점:
- Seg0: 생성 후 4일 경과 → 삭제 대상
- Seg1: 생성 후 3일 경과 → 삭제 대상
- Seg2~Seg4: 유지

시간 기준 선택

# 세그먼트의 마지막 수정 시간 기준
log.message.timestamp.type = CreateTime  # 메시지 생성 시간 (기본값)
# 또는
log.message.timestamp.type = LogAppendTime  # 브로커 저장 시간

크기 기반 Retention

설정

# Broker 레벨 (기본값: 무제한)
log.retention.bytes = -1  # -1은 무제한
 
# 파티션당 100GB 제한
log.retention.bytes = 107374182400

Topic 레벨 설정

# 토픽에 크기 제한 설정
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name my-topic \
    --bootstrap-server localhost:9092 \
    --add-config retention.bytes=10737418240  # 10GB per partition

동작 방식

retention.bytes = 50GB

파티션 크기가 50GB 초과 시:
┌──────┬──────┬──────┬──────┬──────┬──────┐
│ 10GB │ 10GB │ 10GB │ 10GB │ 10GB │ 15GB │  = 65GB
│ Seg0 │ Seg1 │ Seg2 │ Seg3 │ Seg4 │ Seg5 │
└──────┴──────┴──────┴──────┴──────┴──────┘
   ↑
삭제하여 50GB 이하로 유지

결과:
┌──────┬──────┬──────┬──────┬──────┐
│ 10GB │ 10GB │ 10GB │ 10GB │ 15GB │  = 55GB
│ Seg1 │ Seg2 │ Seg3 │ Seg4 │ Seg5 │
└──────┴──────┴──────┴──────┴──────┘

주의사항

중요: log.retention.bytes는 파티션당 적용

토픽: 3 파티션, retention.bytes = 10GB
→ 총 저장 공간 최대 30GB

실제 사용량 계산:
파티션 수 × retention.bytes × replication factor = 최대 사용량

혼합 정책

설정

# 7일 또는 100GB 중 먼저 도달하는 조건으로 삭제
log.retention.hours = 168
log.retention.bytes = 107374182400

동작 논리

IF (segment.age > retention.ms) OR (partition.size > retention.bytes)
    THEN delete segment

Segment 삭제 과정

삭제 검사 주기

# 삭제 검사 간격 (기본 5분)
log.retention.check.interval.ms = 300000

삭제 과정

1. Log Cleaner 스레드가 주기적으로 검사
     ↓
2. Retention 조건 확인
     ↓
3. 삭제 대상 세그먼트 식별
     ↓
4. .deleted 확장자 추가 (마킹)
     ↓
5. log.segment.delete.delay.ms 후 실제 삭제

파일 상태 변화:
00000000000000000000.log
     ↓
00000000000000000000.log.deleted
     ↓
(삭제됨)

삭제 지연

# 세그먼트 삭제 전 대기 시간 (기본 1분)
log.segment.delete.delay.ms = 60000

Cleanup Policy

Delete vs Compact

# 삭제 정책 (기본값)
log.cleanup.policy = delete
 
# 압축 정책
log.cleanup.policy = compact
 
# 둘 다 사용
log.cleanup.policy = delete,compact

정책 비교

정책동작사용 사례
delete오래된 세그먼트 삭제로그, 이벤트 스트림
compact키별 최신 값만 유지상태, 설정
delete,compact압축 후 오래된 것 삭제변경 로그

영구 보관 (무한 Retention)

설정

# 시간 기반 무제한
log.retention.ms = -1
 
# 크기 기반 무제한
log.retention.bytes = -1

주의사항

무한 Retention 시:
✓ 규정 준수 요구사항 충족
✓ 과거 데이터 재처리 가능

✗ 디스크 공간 지속 증가
✗ 복구 시간 증가
✗ 운영 복잡도 증가

권장: Tiered Storage 고려 (Kafka 3.0+)

토픽별 Retention 설정

설정 예시

# 실시간 이벤트: 1일 보관
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name realtime-events \
    --add-config retention.ms=86400000
 
# 로그 데이터: 7일 보관
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name app-logs \
    --add-config retention.ms=604800000
 
# 감사 로그: 1년 보관
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name audit-logs \
    --add-config retention.ms=31536000000
 
# 설정 데이터: 크기 기반 + Compaction
kafka-configs.sh --alter \
    --entity-type topics \
    --entity-name config-data \
    --add-config "cleanup.policy=compact,retention.bytes=1073741824"

설정 확인

# 토픽 설정 조회
kafka-configs.sh --describe \
    --entity-type topics \
    --entity-name my-topic \
    --bootstrap-server localhost:9092
 
# 현재 로그 크기 확인
kafka-log-dirs.sh \
    --bootstrap-server localhost:9092 \
    --describe \
    --topic-list my-topic

디스크 공간 계산

예상 사용량 계산

일일 메시지 양: 100GB
Retention 기간: 7일
Replication Factor: 3
파티션 수: 10

필요 공간:
= 일일 양 × Retention 일수 × Replication Factor
= 100GB × 7 × 3
= 2.1TB

세그먼트 오버헤드 고려 (10%):
= 2.1TB × 1.1
= 2.31TB

디스크 알림 설정

# 디스크 사용량 임계치
# 90% 초과 시 경고 로그
log.dirs.free.space.warning.threshold = 0.1
 
# 95% 초과 시 쓰기 중단
log.dirs.free.space.threshold = 0.05

모니터링

메트릭

JMX 메트릭:
kafka.log:type=Log,name=Size,topic={topic},partition={partition}
→ 파티션별 로그 크기

kafka.log:type=Log,name=NumLogSegments,topic={topic},partition={partition}
→ 세그먼트 수

kafka.log:type=LogCleaner,name=*
→ Log Cleaner 상태

명령행 도구

# 로그 디렉토리 크기 확인
du -sh /kafka-logs/*
 
# 특정 토픽 세그먼트 확인
ls -la /kafka-logs/my-topic-0/
 
# Retention 상태 모니터링
watch -n 60 'df -h /kafka-logs'

관련 문서