LabHub
배우기 러닝패스 코스

注文が二度届き、一度は消えた

保持とコンパクション — トピック設定が残すもの、捨てるもの

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

이 실습은 VM 에서 돕니다

우분투 VM 에 Apache Kafka 4.3.1 이 KRaft 단일 노드로 떠 있습니다 (localhost:9092). 브로커의 보존 검사 주기(log.retention.check.interval.ms)를 10초, 클리너 대기(log.cleaner.backoff.ms)를 5초로 줄여 두어 1분 안에 삭제와 압축을 볼 수 있습니다. 처음 뜨는 데 4분쯤 걸립니다.

목표

시간 보존(retention.ms)이 옛 세그먼트를 지우는 것, 압축(cleanup.policy=compact)이 키마다 마지막 값만 남기는 것, max.message.bytes 가 큰 레코드를 거절하는 것을 직접 보고, 실행 중인 토픽의 설정을 바꿔 봅니다.

왜 중요한가

토픽 설정은 "무엇을 얼마나 오래 남기는가" 를 정합니다. 기본 보존은 7일이고 세그먼트 단위로 지워지기 때문에 retention.ms 가 지났다고 곧바로 사라지지 않습니다 — 활성 세그먼트는 절대 지워지지 않고, 세그먼트가 굴러가야(segment.ms) 지울 수 있습니다. 압축은 다른 종류의 보존입니다. 키가 있는 변경 로그에서 각 키의 마지막 값을 반드시 남겨 주므로, 처음부터 읽으면 현재 상태가 복원됩니다. 이 차이를 모르면 "지웠는데 남아 있다", "남긴다고 했는데 사라졌다" 는 신고를 읽을 수 없습니다.

단계

  1. 토픽 eventsretention.ms=20000, segment.ms=10000 으로 만드세요.
  2. e1·e2·e3 을 넣고 12초 이상 기다린 뒤 e4 를 넣어 세그먼트를 굴리고, 30초쯤 더 기다리세요. 가장 앞 오프셋이 0 이 아니게 되면 /root/kafka/retention.txtearliest=<가장 앞 오프셋>, latest=<로그 끝 오프셋> 두 줄을 쓰세요.
  3. 토픽 customerscleanup.policy=compact, segment.ms=10000, min.cleanable.dirty.ratio=0.01 로 만드세요.
  4. 키 파싱으로 alice:v1, bob:v1, alice:v2, alice:v3 을 넣고 12초 이상 기다린 뒤 carol:v1 을 넣어 세그먼트를 굴리세요. 압축이 끝나면(30초쯤) 처음부터 키와 함께 읽어 /root/kafka/compacted.txt 에 저장하세요. alicev3 한 번만 있어야 합니다.
  5. 토픽 photosmax.message.bytes=1024 로 만들고 2,000자짜리 한 줄(/root/kafka/big2k.txt)을 넣어 보세요. 프로듀서의 stderr 를 /root/kafka/toolarge.txt 에 남기세요 — 거절되어 레코드는 0건이어야 합니다.
  6. kafka-configs.sheventsretention.ms86400000 으로 바꾸세요(토픽을 다시 만들지 말고).
  7. /root/kafka/topic-report.txtevents_retention_ms=86400000, customers_policy=compact, photos_max_bytes=1024, min_insync_default=1, three_broker_min_isr=2 다섯 줄을 쓰세요.

참고

20초만 남기는 토픽

토픽 eventsretention.ms=20000, segment.ms=10000 으로 만드세요.

--create --topic events --partitions 1 --config retention.ms=20000 --config segment.ms=10000. segment.ms 가 없으면 기본 7일 동안 세그먼트가 굴러가지 않아 아무것도 지워지지 않습니다.

옛 세그먼트가 지워진다

e1·e2·e3 을 넣고 12초 이상 기다린 뒤 e4 를 넣어 세그먼트를 굴리고, 30초쯤 더 기다리세요. 가장 앞 오프셋이 0 이 아니게 되면 /root/kafka/retention.txtearliest=<가장 앞 오프셋>, latest=<로그 끝 오프셋> 두 줄을 쓰세요.

kafka-get-offsets.sh --topic events --time earliestevents:0:3 처럼 바뀌면 첫 세그먼트가 지워진 것입니다. 지워지는 단위는 레코드가 아니라 세그먼트라, e1~e3 이 한꺼번에 사라지고 활성 세그먼트의 e4 는 남습니다.

키마다 마지막 값만 남기는 토픽

토픽 customerscleanup.policy=compact, segment.ms=10000, min.cleanable.dirty.ratio=0.01 로 만드세요.

--config cleanup.policy=compact --config segment.ms=10000 --config min.cleanable.dirty.ratio=0.01. dirty ratio 기본값은 0.5 라 로그의 절반이 중복이어야 클리너가 움직입니다 — 실습에서는 거의 0 으로 낮춥니다.

압축 뒤에는 alice 가 하나다

키 파싱으로 alice:v1, bob:v1, alice:v2, alice:v3 을 넣고 12초 이상 기다린 뒤 carol:v1 을 넣어 세그먼트를 굴리세요. 압축이 끝나면(30초쯤) 처음부터 키와 함께 읽어 /root/kafka/compacted.txt 에 저장하세요. alicev3 한 번만 있어야 합니다.

활성 세그먼트는 압축되지 않으므로 carol 로 굴려야 합니다. 읽을 때 --formatter-property print.key=true 를 주면 alice\tv3 꼴입니다. alice 가 아직 셋이면 클리너가 돌기 전이니 10초 뒤 다시 읽으세요.

너무 큰 레코드는 거절된다

토픽 photosmax.message.bytes=1024 로 만들고 2,000자짜리 한 줄(/root/kafka/big2k.txt)을 넣어 보세요. 프로듀서의 stderr 를 /root/kafka/toolarge.txt 에 남기세요 — 거절되어 레코드는 0건이어야 합니다.

head -c 2000 /dev/zero | tr '\0' y > big2k.txt; echo >> big2k.txt. 브로커가 배치 크기 상한으로 거절하면 프로듀서 로그에 RecordTooLarge 계열 오류가 찍히고 kafka-get-offsets.sh 는 0 을 냅니다.

실행 중에 설정을 바꾼다

kafka-configs.sheventsretention.ms86400000 으로 바꾸세요(토픽을 다시 만들지 말고).

kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name events --alter --add-config retention.ms=86400000. 운영 문서의 'Modifying topics' 그대로입니다. --describe 로 확인하세요.

설정값으로 정리한다

/root/kafka/topic-report.txtevents_retention_ms=86400000, customers_policy=compact, photos_max_bytes=1024, min_insync_default=1, three_broker_min_isr=2 다섯 줄을 쓰세요.

앞 셋은 kafka-configs.sh --describe 로 지금 값을 읽어 적습니다(채점기도 그렇게 봅니다). 뒤 둘은 토픽 설정 문서의 min.insync.replicas 항목 — 기본값과, 복제 계수 3 일 때의 전형적인 값입니다.