토픽 컴팩션
토픽 컴팩션 (Topic Compaction)
메시지를 계속 쌓아 두다 보면 소비자가 전체 로그를 처음부터 다시 읽으며 "되감기"해야 하는 부담이 생겨요. 그런데 주식 티커처럼 최신 값만 필요한 경우라면 전체 이력이 꼭 필요하지 않죠. 토픽 컴팩션(Topic Compaction)은 이런 때 토픽의 백로그를 정리해 나중 메시지에 가려진(obscured) 이전 메시지를 제거하고 키별 최신 메시지만 남기는 기능이에요. 이 글에서는 컴팩션의 동작 원리와 관련 설정을 정리해 드릴게요.
출처: 문서
본문
Pulsar는 메시지 데이터의 확장성이 뛰어난 영구 저장소를 핵심 목표로 만들어진 시스템이에요. Pulsar 토픽을 사용하면 메시지 순서를 유지하면서 원하는 만큼 많은 미확인 메시지를 영구적으로 저장할 수 있어요. 기본적으로 Pulsar는 토픽에 생성된 모든 미확인/미처리 메시지를 저장해요. 토픽에 미확인 메시지를 많이 쌓아 두는 것은 여러 Pulsar 사용 사례에서 필요하지만, 그만큼 소비자가 전체 메시지 로그를 "되감기"하는 데 시간이 많이 걸릴 수 있죠.
토픽 컴팩션에 대한 더 실용적인 가이드는 토픽 컴팩션 쿡북을 보세요.
일부 사용 사례에서 소비자는 토픽 로그의 완전한 "이미지"가 필요 없어요. 더 "얕은" 로그 이미지를 만들기 위해 몇 개의 값만 필요할 수도 있고, 어쩌면 가장 최근 값 하나만 필요할 수도 있어요. 이런 종류의 사용 사례를 위해 Pulsar는 토픽 컴팩션을 제공해요. 토픽에 컴팩션을 실행하면 Pulsar가 토픽의 백로그를 훑으면서 나중 메시지에 가려진 메시지를 제거해요. 즉 토픽 컴팩션은 토픽을 키(key)별로 훑으면서 각 키와 연결된 가장 최근 메시지만 남기는 거예요.
Pulsar의 토픽 컴팩션 기능:
- 토픽 로그를 더 빠르게 "되감기"할 수 있게 해줘요.
- 영구 토픽에만 적용돼요.
- 백로그가 특정 크기에 도달하면 자동으로 트리거되거나, 명령줄을 통해 수동으로 트리거할 수 있어요. 토픽 컴팩션 쿡북을 보세요.
- 개념적으로도 운영적으로도 보존(retention) 및 만료(expiry)와는 구별돼요. 다만 토픽 컴팩션은 보존을 존중해요. 보존이 토픽의 메시지 백로그에서 메시지를 제거했다면, 그 메시지는 컴팩션된 토픽 ledger에서도 읽을 수 없어요.
토픽 컴팩션 예시: 주식 티커 컴팩션된 Pulsar 토픽의 예시 사용 사례는 주식 티커(stock ticker) 토픽이에요. 주식 티커 토픽에서 각 메시지는 매수 대상 주식의 타임스탬프가 찍힌 달러 가치를 담아요 (메시지 키가 주식 심볼을 보유하죠, 예:
AAPL또는GOOG). 주식 티커에서는 주식의 가장 최근 값만 신경 쓰고 이력 데이터는 관심이 없을 수 있어요 (즉 키별 토픽 메시지 시퀀스의 완전한 이미지를 만들 필요가 없죠). 이 경우 컴팩션은 소비자가 가려진 메시지를 다시 되감을 필요가 없게 만들어 주므로 매우 유용해요.
토픽 컴팩션 동작 방식
토픽 컴팩션을 CLI로 트리거하면 다음 단계로 동작해요:
-
Pulsar가 토픽 전체를 처음부터 끝까지 반복해요.
컴팩션 루틴은 만나는 각 키에 대해 그 키가 가장 최근에 나타난 위치를 기록해 둬요.
-
그런 다음 브로커가 새 BookKeeper ledger를 만들고 토픽의 각 메시지를 두 번째로 반복해요. 각 메시지에 대해:
- 키가 해당 키의 최신 발생과 일치하면, 키의 데이터 페이로드, 메시지 ID, 메타데이터를 새로 만든 ledger에 기록해요.
- 키가 최신과 일치하지 않으면 그 메시지는 건너뛰고 그대로 둬요.
- 어떤 메시지가 빈 페이로드를 갖고 있으면 건너뛰고 삭제된 것으로 간주해요 (키-값 데이터베이스의 tombstones 개념과 비슷해요).
-
토픽을 두 번째로 반복한 끝에 새로 만든 BookKeeper ledger를 닫고, 다음 두 가지를 토픽의 메타데이터에 기록해요:
- BookKeeper ledger의 ID
- 마지막으로 컴팩션된 메시지의 메시지 ID (이것을 토픽의 컴팩션 지평선(horizon)이라 불러요)
이 메타데이터가 기록되면 컴팩션이 완료돼요.
-
최초 컴팩션 작업 이후에는 토픽을 소유한 Pulsar 브로커가 컴팩션 지평선과 컴팩션된 백로그에 향후 변경이 있을 때마다 알림을 받아요. 이런 변경이 발생하면:
- 컴팩션 읽기를 활성화한 클라이언트(소비자/리더)가 토픽에서 메시지를 읽으려 할 때:
- 메시지 ID가 컴팩션 지평선보다 크거나 같으면 평소처럼 토픽에서 읽거나,
- 메시지 ID가 컴팩션 지평선보다 낮으면 컴팩션 지평선부터 읽기 시작해요.
- 컴팩션 읽기를 활성화한 클라이언트(소비자/리더)가 토픽에서 메시지를 읽으려 할 때:
컴팩션 설정
토픽 컴팩션 동작은 다양한 브로커 설정으로 구성할 수 있어요:
주요 설정 파라미터
compactionRetainNullKey: 컴팩션 중 null 키를 보존할지 여부를 제어해요.true로 설정하면 null 키를 가진 메시지가 컴팩션된 ledger에 보존돼요.false(기본값)면 null 키 메시지는 키가 없는 메시지로 취급되어 컴팩션 중 제거될 수 있어요.brokerServiceCompactionThreshold: 토픽 백로그에 대한 자동 컴팩션을 트리거하는 임계값 크기(바이트)예요. 토픽 백로그가 이 크기를 초과하면 컴팩션이 자동으로 트리거돼요.
null 키 처리
compactionRetainNullKey 파라미터는 키가 없는 메시지를 포함하는 토픽에서 특히 중요해요. 이 설정은 컴팩션 과정에서 그런 메시지를 어떻게 처리할지 결정해요:
- 활성화(
true): null 키 메시지가 컴팩션 중 보존되어, 키가 없는 메시지도 컴팩션된 뷰에 계속 접근 가능해요. - 비활성화(
false): null 키 메시지는 컴팩션 중 제거될 수 있어요. 키가 없으면 제대로 중복 제거할 수 없기 때문이에요.
이 설정은 키가 있는 메시지와 없는 메시지가 섞인 토픽에 유용해요. 관리자가 컴팩션된 토픽에 키 없는 메시지를 보존할지 여부를 제어할 수 있게 해주죠.
성능 고려 사항
- 컴팩션 빈도: 저장 공간 절약과 CPU/I/O 오버헤드 사이의 균형을 잡아요.
- 토픽 크기: 토픽이 클수록 컴팩션에 더 오래 걸리지만, 컴팩션의 이득이 더 클 수도 있어요.
- 키 분포: 고유 키가 많은 토픽은 컴팩션의 이득이 더 적어요.
더 알아보기 (Learn more)
- 토픽 컴팩션 쿡북 — CLI로 컴팩션을 실행하는 실제 절차를 따라 해 보세요.
- 아키텍처 개요 — ledgers와 브로커 구조를 이해해요.
- 보존 및 만료 쿡북 — 보존·만료와 컴팩션의 차이를 정리해요.
- 메시징 개념 — 키와 페이로드의 기본 개념을 익혀요.