Kafka의 로그 정리 정책은 토픽 설정 cleanup.policy로 결정됩니다. delete는 보존 기한이 지나거나 크기 상한을 넘은 세그먼트를 통째로 삭제하고, compact는 키별로 최신 레코드만 남기고 중복 오프셋을 제거합니다. 이 두 정책이 Tiered Storage(원격 스토리지, KIP-405)와 어떻게 상호작용하는지가 헷갈리기 쉬운 부분이라 소스를 직접 확인했습니다.
압축 토픽은 원격 스토리지 대상이 될 수 없다
storage/internals/log/LogConfig.java에는 명시적인 검증 로직이 있습니다. cleanup.policy에 compact가 포함된 토픽에는 remote.storage.enable=true를 켤 수 없고, 시도하면 바로 ConfigException이 발생합니다. 예외 메시지도 "Remote log storage only supports topics with cleanup.policy=delete or cleanup.policy being an empty list"로 명확합니다.
__consumer_offsets처럼 compact 정책을 쓰는 내부 토픽이나, 애플리케이션에서 상태 저장용으로 compact를 쓰는 토픽을 Tiered Storage 대상으로 잘못 설계하면 이 단계에서 막힙니다. 처음부터 Tiered Storage 후보는 delete 정책을 쓰는 이벤트/로그성 대용량 토픽으로 한정해서 설계하는 게 맞습니다.
전역 스위치와 토픽 스위치는 별개다
Tiered Storage를 켜는 스위치가 두 단계로 나뉘어 있습니다.
remote.log.storage.system.enable: 클러스터 전역 스위치, 기본값falseremote.storage.enable: 토픽별 스위치, 기본값false
전역 스위치를 켜지 않은 채로 토픽 설정만 켜면 무시되거나 오류가 납니다. 전역 스위치는 클러스터 부팅 시점에 결정해야 하는 값이라, 런타임에 브로커마다 다르게 설정하는 방식은 지원되지 않습니다.
log.local.retention.ms의 -2는 무한 보존이 아니다
Tiered Storage를 쓰면 로컬 디스크에는 최근 데이터만 남기고 오래된 세그먼트는 RemoteStorageManager 플러그인을 통해 원격으로 오프로드합니다. 이때 로컬 보존 기간을 정하는 게 log.local.retention.ms인데, 기본값이 -2입니다.
-2는 무한 보존을 뜻하는 게 아니라 "글로벌 log.retention.ms 값을 그대로 따른다"는 센티널 값입니다. -1(무한 보존)과 혼동하기 쉬운 지점이라, 명시적으로 값을 정하지 않았을 때 실제로 어떻게 동작하는지는 정확히 알고 넘어가는 게 좋습니다. 로컬 디스크 용량이 한정적인 환경이라면 아예 명시적으로 값을 지정하는 편이 의도를 분명하게 만듭니다.
되돌릴 때도 가드가 걸린다
클러스터 차원에서 Tiered Storage를 끄려면, 활성화된 토픽들을 먼저 정리하거나 remote.log.delete.on.disable=true를 함께 설정해야 합니다. 이 순서를 지키지 않고 바로 끄려고 하면 예외로 막힙니다. 의도된 안전장치이긴 하지만, 장애 상황에서 급하게 롤백해야 할 때는 이 절차 자체가 걸림돌이 될 수 있다는 점을 미리 알아두는 편이 낫습니다.
정리
Tiered Storage를 도입할 때 챙길 순서는 이렇습니다. 먼저 대상 토픽이 delete 정책인지 확인하고, 전역 스위치와 토픽 스위치를 순서대로 켭니다. 오프로드 스레드 풀(remote.log.manager.thread.pool.size, remote.log.manager.copier.thread.pool.size)은 읽기와 업로드가 분리되어 있으니 원격 저장소의 처리량 특성에 맞춰 각각 튜닝합니다. 세그먼트 크기(log.segment.bytes)가 오프로드 단위이기도 하므로, 오프로드 주기(remote.log.manager.task.interval.ms, 기본 30초)와 함께 보면서 너무 잦은 소규모 업로드가 생기지 않는지 확인하는 것도 필요합니다.