티어드 스토리지
티어드 스토리지 (Tiered Storage)
이 페이지는 Kafka의 티어드 스토리지 기능을 소개해요. 오래된 로그 세그먼트를 로컬 디스크가 아닌 HDFS·S3 같은 외부 저장소로 옮겨서 로컬 디스크 부담을 줄이는 방식이에요. 브로커·토픽 설정과 퀵스타트 예제가 포함돼 있어요.
출처: 문서
본문
티어드 스토리지 개요 (Tiered Storage Overview)
Kafka 데이터는 대부분 tail 읽기를 사용하는 스트리밍 방식으로 소비됩니다. tail 읽기는 디스크 읽기 대신 OS의 페이지 캐시를 활용해 데이터를 제공합니다. 오래된 데이터는 일반적으로 백필(backfill)이나 장애 복구 목적으로 디스크에서 읽히며 빈도가 낮습니다.
티어드 스토리지 접근 방식에서 Kafka 클러스터는 로컬(local)과 원격(remote) 두 계층의 저장소로 구성됩니다. 로컬 계층은 Kafka 브로커의 로컬 디스크를 사용해 로그 세그먼트를 저장하는 현재 Kafka와 동일합니다. 새 원격 계층은 HDFS나 S3 같은 외부 저장 시스템을 사용해 완료된 로그 세그먼트를 저장합니다. 자세한 내용은 KIP-405를 확인하세요.
구성 (Configuration)
브로커 구성 (Broker Configurations)
기본적으로 Kafka 서버는 티어드 스토리지 기능을 활성화하지 않습니다. remote.log.storage.system.enable은 브로커에서 티어드 스토리지 기능을 활성화할지 여부를 제어하는 속성입니다. "true"로 설정하면 이 기능이 활성화됩니다.
RemoteStorageManager는 원격 로그 세그먼트와 인덱스의 수명주기를 제공하는 인터페이스입니다. Kafka 서버는 RemoteStorageManager의 기본 제공(out-of-the-box) 구현을 제공하지 않습니다. 사용자는 remote.log.storage.manager.class.name과 remote.log.storage.manager.class.path를 구성해 RemoteStorageManager의 구현을 지정해야 합니다.
RemoteLogMetadataManager는 강하게 일관된 의미론으로 원격 로그 세그먼트에 대한 메타데이터의 수명주기를 제공하는 인터페이스입니다. 기본적으로 Kafka는 저장소가 내부 토픽인 구현을 제공합니다. 이 구현은 remote.log.metadata.manager.class.name과 remote.log.metadata.manager.class.path를 구성해 변경할 수 있습니다. 기본 kafka 내부 토픽 기반 구현을 채택할 때 remote.log.metadata.manager.listener.name은 기본 RemoteLogMetadataManager 구현이 만드는 클라이언트가 어떤 리스너를 사용할지 지정하는 필수 속성입니다.
토픽 구성 (Topic Configurations)
티어드 스토리지 기능에 대한 브로커 측 구성을 올바르게 설정한 후에도 토픽 수준에서 설정해야 할 구성이 여전히 있습니다. remote.storage.enable은 토픽이 티어드 스토리지를 사용할지 여부를 결정하는 스위치입니다. 기본값은 false입니다. remote.storage.enable 속성을 활성화한 후 고려할 다음 사항은 로그 보존입니다. 토픽에 대해 티어드 스토리지가 활성화되면 설정해야 할 추가 로그 보존 구성이 2가지 있습니다.
local.retention.msretention.mslocal.retention.bytesretention.bytes
local 접두사가 붙은 구성은 "로컬" 로그 파일이 원격 저장소로 이동하기 전에 받아들일 수 있는 시간/크기를 지정하고, 그 후 삭제됩니다. 설정되지 않으면 retention.ms와 retention.bytes의 값이 사용됩니다.
퀵스타트 예제 (Quick Start Example)
Apache Kafka는 기본 제공 RemoteStorageManager 구현을 제공하지 않습니다. 티어드 스토리지 기능을 미리 보려면 통합 테스트를 위해 구현된 LocalTieredStorage를 사용할 수 있습니다. 이 구현은 로컬 저장소에 임시 디렉터리를 만들어 원격 저장소를 시뮬레이션합니다.
LocalTieredStorage를 채택하려면 테스트 라이브러리를 로컬에서 빌드해야 합니다.
# please checkout to the specific version tag you're using before building it
# ex: `git checkout 4.3.1`
$ ./gradlew clean :storage:testJar
빌드가 성공하면 storage/build/libs 아래에 kafka-storage-x.x.x-test.jar 파일이 있어야 합니다. 다음으로 브로커 측에 티어드 스토리지 기능을 활성화하는 구성을 설정합니다.
# Sample KRaft broker server.properties listening on PLAINTEXT://:9092
remote.log.storage.system.enable=true
# Setting the listener for the clients in RemoteLogMetadataManager to talk to the brokers.
remote.log.metadata.manager.listener.name=PLAINTEXT
# Please provide the implementation info for remoteStorageManager.
# This is the mandatory configuration for tiered storage.
# Here, we use the `LocalTieredStorage` built above.
remote.log.storage.manager.class.name=org.apache.kafka.server.log.remote.storage.LocalTieredStorage
remote.log.storage.manager.class.path=/PATH/TO/kafka-storage-4.3.1-test.jar
# These 2 prefix are default values, but customizable
remote.log.storage.manager.impl.prefix=rsm.config.
remote.log.metadata.manager.impl.prefix=rlmm.config.
# Configure the directory used for `LocalTieredStorage`
# Note, please make sure the brokers need to have access to this directory
rsm.config.dir=/tmp/kafka-remote-storage
# For single broker cluster, set this to 1. Default is 3 for clusters with 3 or more brokers.
rlmm.config.remote.log.metadata.topic.replication.factor=1
# The minimum number of replicas that must acknowledge a write to remote log metadata topic.
# Default value is 2. For single broker cluster (replication factor = 1), set this to 1.
rlmm.config.remote.log.metadata.topic.min.isr=1
# Try to speed up the log retention check interval for testing
log.retention.check.interval.ms=1000
퀵스타트 가이드를 따라 kafka 환경을 시작하세요. 그런 다음 티어드 스토리지가 활성화된 토픽을 다음 구성으로 만듭니다.
# remote.storage.enable=true -> enables tiered storage on the topic
# local.retention.ms=1000 -> The number of milliseconds to keep the local log segment before it gets deleted.
# Note that a local log segment is eligible for deletion only after it gets uploaded to remote.
# retention.ms=3600000 -> when segments exceed this time, the segments in remote storage will be deleted
# segment.bytes=1048576 -> for test only, to speed up the log segment rolling interval
# file.delete.delay.ms=10000 -> for test only, to speed up the local-log segment file delete delay
$ bin/kafka-topics.sh --create --topic tieredTopic --bootstrap-server localhost:9092 \
--config remote.storage.enable=true --config local.retention.ms=1000 --config retention.ms=3600000 \
--config segment.bytes=1048576 --config file.delete.delay.ms=1000
tieredTopic 토픽에 메시지를 보내 로그 세그먼트를 롤링해 봅시다.
$ bin/kafka-producer-perf-test.sh --bootstrap-server localhost:9092 --topic tieredTopic --num-records 1200 --record-size 1024 --throughput -1
그런 다음 활성 세그먼트가 롤링된 후, 이전 세그먼트는 원격 저장소로 이동되어 삭제되어야 합니다. 이는 위에서 구성한 원격 로그 디렉터리를 확인함으로써 검증할 수 있습니다. 예:
$ ls /tmp/kafka-remote-storage/kafka-tiered-storage/tieredTopic-0-jF8s79t9SrG_PNqlwv7bAA
00000000000000000000-knnxbs3FSRyKdPcSAOQC-w.index
00000000000000000000-knnxbs3FSRyKdPcSAOQC-w.snapshot
00000000000000000000-knnxbs3FSRyKdPcSAOQC-w.leader_epoch_checkpoint
00000000000000000000-knnxbs3FSRyKdPcSAOQC-w.timeindex
00000000000000000000-knnxbs3FSRyKdPcSAOQC-w.log
마지막으로 처음부터 일부 데이터를 소비해 오프셋 번호를 출력해, 원격 저장소에서 오프셋 0을 성공적으로 가져오는지 확인할 수 있습니다.
$ bin/kafka-console-consumer.sh --topic tieredTopic --from-beginning --max-messages 1 --bootstrap-server localhost:9092 --formatter-property print.offset=true
KRaft 모드에서는 토픽 수준에서 티어드 스토리지를 비활성화해 원격 로그를 읽기 전용으로 만들거나, 모든 원격 로그를 완전히 삭제할 수 있습니다.
원격 로그를 읽기 전용으로 만들고 더 이상 로컬 로그가 원격 저장소로 복사되지 않게 하려면 토픽에 remote.storage.enable=true,remote.log.copy.disable=true를 설정할 수 있습니다.
참고: 또한 local.retention.ms와 local.retention.bytes를 retention.ms, retention.bytes와 같은 값으로 설정하거나 "-2"로 설정해야 합니다. 원격 로그 복사를 비활성화한 후에는 로컬 보존 정책이 더 이상 적용되지 않아 사용자를 혼란스럽게 하고 예상치 못한 디스크 가득 참(disk full)을 일으킬 수 있기 때문입니다.
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --entity-type topics --entity-name tieredTopic \
--add-config 'remote.storage.enable=true,remote.log.copy.disable=true,local.retention.ms=-2,local.retention.bytes=-2'
모든 원격 로그가 삭제된 채 토픽 수준에서 티어드 스토리지를 완전히 비활성화하려면 토픽에 remote.storage.enable=false,remote.log.delete.on.disable=true를 설정할 수 있습니다.
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --entity-type topics --entity-name tieredTopic \
--add-config 'remote.storage.enable=false,remote.log.delete.on.disable=true'
토픽 수준에서 티어드 스토리지 기능을 다시 활성화할 수도 있습니다. 클러스터 수준에서 티어드 스토리지를 비활성화하려면 티어드 스토리지가 활성화된 토픽을 명시적으로 삭제해야 한다는 점에 유의하세요. 티어드 스토리지를 사용하는 토픽을 삭제하지 않고 클러스터 수준에서 티어드 스토리지를 비활성화하려 하면 시작 중에 예외가 발생합니다.
$ bin/kafka-topics.sh --delete --topic tieredTopic --bootstrap-server localhost:9092
토픽이 삭제된 후 브로커 구성에서 remote.log.storage.system.enable=false로 설정해도 안전합니다.
제한 사항 (Limitations)
티어드 스토리지는 대부분의 사용 사례에서 작동하지만 다음 제한 사항을 인지하는 것이 여전히 중요합니다.
- 컴팩션(compacted) 토픽 미지원.
- 브로커 수준에서 티어드 스토리지를 비활성화하기 전에 활성화된 모든 토픽에서 티어드 스토리지를 비활성화해야 함.
- 티어드 스토리지와 관련된 admin 작업은 3.0 버전부터의 클라이언트에서만 지원.
- 프로듀서 스냅샷 파일이 없는 로그 세그먼트 미지원. 이는 토픽이 v2.8.0 이전에 생성된 경우 발생할 수 있음.
자세한 내용은 Kafka Tiered Storage GA 릴리스 노트를 확인하세요.
더 알아보기 (Learn more)
RemoteStorageManager와RemoteLogMetadataManager두 인터페이스가 티어드 스토리지의 핵심이에요.- 로컬 보존(
local.retention.*)과 원격 보존(retention.*)을 구분해서 설정해야 해요. - 클러스터 수준 비활성화 전에는 티어드 스토리지 토픽을 먼저 삭제해야 해요.