Apache Pulsar 5.0.0-M1: Scalable Topics·Oxia·V5 Client로 스트리밍 메시징의 운영 경계를 다시 그은 프리뷰
왜 5.0.0-M1을 지금 봐야 하나
2026년 6월 23일 공개된 Apache Pulsar 5.0.0-M1은 GA가 아니다. 릴리스 노트도 preview이며 production 용도가 아니다라고 못 박는다. 그럼에도 운영자가 지금 이 프리뷰를 읽어야 하는 이유는 분명하다. Pulsar 5.0이 무엇을 "더 넣는다"의 문제가 아니라, 토픽 병렬화·클라이언트 API·메타데이터 저장소라는 세 가지 오래된 경계를 한 번에 다시 정하기 시작했기 때문이다.
이번 M1에서 특히 중요한 축은 네 가지다.
- Scalable Topics: 고정 파티션 대신 해시 범위 세그먼트로 토픽을 늘리고 줄인다.
- V5 Java Client: 파티션 수를 클라이언트 API 밖으로 밀어내고, 소비 모델을
QueueConsumer·StreamConsumer·CheckpointConsumer로 분리한다. - Oxia 권장화: 새 클러스터의 권장 메타데이터 저장소가 ZooKeeper에서 Oxia로 이동한다.
- 운영 보조면 정리: 구조화 로그, Gradle 전환, IO connector 분리,
javax→jakarta전환이 함께 들어온다.
즉, Pulsar 5.0은 "메시지 브로커에 기능 몇 개 추가"가 아니라 메시징 시스템의 병렬화 방식과 운영면을 다시 설계하는 릴리스다.
한 장으로 보는 5.0.0-M1 변화
Scalable Topics: 파티션 수를 바꾸지 않고도 병렬도를 바꾸는 방향
Pulsar의 기존 partitioned topic 모델은 병렬화에 효과적이지만, 운영자가 한 번쯤은 같은 문제를 겪는다.
- 파티션 수를 늘리면 key ordering을 안전하게 유지하기 어렵다.
- 파티션 수 자체가 클라이언트 API에 스며들어 있다.
- 재파티셔닝은 보통 애플리케이션과 운영 절차를 동시에 건드린다.
PIP-460은 이 문제를 해결하기 위해 Scalable Topics(Topics v5) 를 새 토픽 타입으로 제안한다. 핵심 아이디어는 단순하다.
- 토픽 전체를 고정 파티션 집합으로 보지 않는다.
- 대신
[0x0000, 0xFFFF]해시 공간을 여러 range segment로 나눈다. - 부하가 늘면 세그먼트를 둘로 split하고, 줄면 다시 merge한다.
- 메시지 키는
murmurHash3_32(key) & 0xFFFF가 떨어지는 범위의 세그먼트로 라우팅한다.
이 방식의 장점은 병렬도 변화가 전역 재배치가 아니라 특정 범위의 국소 변화가 된다는 점이다. 기존 partitioned topic처럼 파티션 개수 전체를 바꾸면서 모든 라우팅 규칙을 흔들지 않아도 된다.
또 하나 중요한 점은, 토폴로지 변경이 클라이언트에게 push된다는 것이다. 릴리스 노트와 PIP-460/PIP-466은 V5 클라이언트가 persistent, push-based lookup session을 통해 세그먼트 DAG 변경을 받도록 설계됐다고 설명한다. 운영자가 토픽을 split하거나 자동 split이 일어나도, 클라이언트가 폴링으로 파티션 수를 다시 읽는 모델이 아니다.
운영 관점에서 보면 토픽을 다음처럼 다시 정의하는 셈이다.
| 기존 질문 | 5.0에서 바뀌는 질문 |
|---|---|
| 파티션을 몇 개로 시작해야 하나? | 어떤 키 공간 범위를 언제 split/merge하게 둘 것인가? |
| 파티션 수 변경이 ordering에 미치는 영향은? | 특정 range split/merge 시 drain-before-assign으로 ordering을 어떻게 지킬 것인가? |
| 클라이언트가 파티션 개수를 얼마나 알아야 하나? | 클라이언트가 토픽 토폴로지를 직접 알 필요가 있는가? |
다만 이번 M1은 어디까지나 preview다. 릴리스 노트는 production 용도가 아니라고 명시하고 있고, PIP-460도 일부 기능(예: full geo-replication, transaction, 일부 stream processing connector)은 5.0 LTS 이후로 미뤄질 수 있다고 적는다. 즉, 지금 바로 본선 배치보다는 설계 방향 검증용으로 보는 것이 맞다.
V5 Java Client: 파티션을 API 바깥으로 밀어낸다
Pulsar의 현재 Java client API는 오랜 기간 기능이 누적되며 커졌다. PIP-466이 지적하는 핵심 문제는 두 가지다.
TopicMessageId,getPartitionsForTopic(),MessageRouter처럼 파티션 개념이 API 타입 시스템에 깊게 박혀 있다.Consumer하나가 Shared/Exclusive/Key_Shared/Failover를 모두 감싸면서, 어떤 메서드는 런타임에서만 금지된다.
V5는 이 문제를 "새 모듈을 추가하는 방식"으로 푼다. 기존 pulsar-client와 pulsar-client-api를 깨지 않고, 추가 모듈 pulsar-client-v5 를 도입한다. 이 점이 중요하다. 운영자는 기존 애플리케이션을 한 번에 전환하지 않아도 된다.
새 소비 모델
| 타입 | 의도 | 운영 의미 |
|---|---|---|
QueueConsumer | 병렬 work queue 처리, 개별 ack, DLQ 친화적 | 메시지 큐성 워크로드를 명시적으로 분리 |
StreamConsumer | 순서 보장, cumulative ack | 스트림 처리/ordered consumption에 맞춤 |
CheckpointConsumer | Flink/Spark 같은 외부 처리기가 자체 위치를 관리 | 파이프라인 프레임워크와의 경계 정리 |
이 설계는 "하나의 Consumer에 의미가 섞여 있는 문제"를 없앤다. 예를 들어 Shared에서 cumulative ack가 안 되는 것을 런타임 예외로 배우는 대신, 컴파일 단계에서 소비 모델을 선택하게 만든다.
기존 토픽에서의 단계적 전환
PIP-475가 중요한 이유는 여기 있다. Pulsar 팀은 "V5 SDK를 먼저 깔고, 토픽은 나중에 migrate"하는 경로를 설계했다.
- V5 SDK는 기존
persistent://...regular topic을 바로 끊지 않는다. - 먼저 synthetic layout / legacy segments 형태로 기존 토픽을 다룬다.
- 이후
POST /admin/v2/scalable-topics/{tenant}/{namespace}/{topic}/migrate같은 관리 연산으로 토픽을 단일 원자적 단계에서 scalable topic으로 바꾼다. - 이 전환은 one-way다. 다시 regular topic으로 되돌리는 경로는 지원하지 않는다.
이 점은 운영적으로 중요하다. 토픽 마이그레이션을 위해 데이터를 복사하거나 커서를 새로 만들지 않는 대신, 애플리케이션 클라이언트 롤아웃이 선행 조건이 된다. 다시 말해 Pulsar 5.0 migration은 스토리지 마이그레이션보다 클라이언트 프로토콜 이행 프로젝트에 가깝다.
Oxia 권장화: 메타데이터 저장소 이행이 제품 기능이 되다
Pulsar 5.0.0-M1의 또 다른 큰 변화는 Oxia가 새 클러스터의 권장 메타데이터 저장소가 된다는 점이다. 릴리스 노트는 ZooKeeper가 계속 지원되지만, scalable topics는 Oxia의 streaming watch session과 특히 잘 맞는다고 설명한다.
여기서 오해하면 안 되는 점이 있다. Oxia는 BookKeeper를 대체하는 데이터 저장소가 아니다. 메시지 본문과 managed ledger는 계속 BookKeeper/data plane에 머문다. 바뀌는 것은 다음 같은 제어면 메타데이터다.
- 브로커 조정
- 토픽/네임스페이스 메타데이터
- 정책과 lookup 상태
- metadata store watch / session 모델
왜 이행 프레임워크가 함께 중요한가
PIP-454는 단순히 "Oxia를 새로 지원한다"가 아니라, metadata store migration framework 자체를 제안한다. 핵심은 DualMetadataStore다.
- 기존 source store(ZooKeeper)를 그대로 감싼다.
- migration 시작 전까지 target store(Oxia)는 lazy init한다.
- 먼저 broker/bookie의 ephemeral node를 target에 재생성한다.
- 그 뒤 metadata write를 막은 read-only 상태에서 persistent metadata를 복사한다.
PREPARATION → COPYING → COMPLETED단계로 진행한다.
이 접근은 dual-write/dual-read를 피하고, 이행 중 메타데이터 일관성을 보장하는 쪽을 택한다. 대가도 분명하다. 이행 중 write path 일부가 read-only 제약을 받으므로, 운영자는 "정말 무중단인가"가 아니라 "데이터 plane을 멈추지 않으면서 제어면 write를 얼마나 짧게 묶어둘 수 있는가" 를 검증해야 한다.
운영자가 실제로 확인할 질문
- ZooKeeper 앙상블과 Oxia를 동시에 관찰할 메트릭/로그가 있는가?
- broker/bookie ephemeral node 재생성이 실패했을 때 복구 절차가 자동으로 충분한가?
- metadata write를 막는 동안 namespace 정책 변경, topic auto-creation, ledger rollover 등 주변 제어면 작업이 어떤 영향을 받는가?
- BookKeeper는 그대로인데 metadata store만 바뀔 때, 장애 시 책임 경계가 더 단순해지는가 아니면 디버깅 경로가 하나 더 늘어나는가?
Pulsar 5.0의 Oxia 권장화는 단순한 "ZooKeeper 대체"가 아니라, watch-heavy control plane을 어떻게 더 현대적인 session/stream 모델로 옮길 것인가에 대한 실험이라고 보는 편이 정확하다.
보조 변화도 무시하면 안 된다
Scalable Topics와 Oxia가 headline이지만, M1에는 실제 업그레이드 위험을 만들 수 있는 보조 변화도 많이 들어 있다.
1) 구조화 로그 (slog)
릴리스 노트와 PIP-467에 따르면 Pulsar는 broker, client, managed ledger, functions, metadata 영역 전반에서 slog 기반 구조화 로그를 채택한다. PULSAR_LOG_FORMAT으로 flat JSON 또는 OpenTelemetry 로그 출력을 고를 수 있다.
이 변화의 의미는 "로그가 예뻐졌다"가 아니다.
- 운영자는 문자열 regex 대신 키-값 필터로 문제를 찾을 수 있다.
- topic, cursor, ledger 같은 반복 컨텍스트를 구조화 필드로 넣을 수 있다.
- log pipeline이 기존 text parser에 의존했다면 ingestion 규칙을 다시 확인해야 한다.
2) javax.* → jakarta.*
커스텀 plugin, interceptor, auth provider를 직접 빌드해 쓰는 팀에게는 이게 생각보다 큰 변화다. 릴리스 노트는 관련 확장을 재컴파일해야 한다고 분명히 적는다. 단순 API rename 같아 보여도, 빌드 체인·의존성 충돌·컨테이너 이미지 캐시가 한 번에 깨질 수 있다.
3) Maven → Gradle
소스 빌드를 직접 하거나 CI에서 Pulsar를 패치해 쓰는 팀은 mvn이 아니라 ./gradlew로 전환해야 한다. 이건 서버 기능 변화는 아니지만, 포크 운영·사내 패치·커스텀 커넥터 빌드에는 직접 영향을 준다.
4) IO connectors 분리
Pulsar core 릴리스에서 커넥터가 빠져나가면, 커넥터 수명주기가 코어와 따로 간다. 운영자는 이를 장점으로 볼 수도 있고 부담으로 볼 수도 있다.
- 장점: connector fix가 core upgrade 없이 나올 수 있다.
- 부담: 버전 호환성 검증 매트릭스가 늘어난다.
5) Etcd metadata backend 제거
Etcd를 메타스토어로 쓰던 환경은 5.0 업그레이드 전에 ZooKeeper나 Oxia로 옮겨야 한다. 소수 사례일 수 있지만, 해당 팀에게는 사실상 사전 마이그레이션이 업그레이드 선행 조건이다.
이번 프리뷰가 바꾸는 운영 사고방식
Pulsar 4.x까지의 운영 질문이 "토픽 수·파티션 수·브로커 수를 어떻게 맞출 것인가"였다면, 5.0 프리뷰 이후의 질문은 좀 더 제어면 중심으로 이동한다.
| 예전 사고방식 | 5.0 프리뷰 이후 질문 |
|---|---|
| 파티션 증설 시 ordering을 어떻게 보전할까? | range split/merge와 drain-before-assign이 실제 워크로드에서 얼마나 안정적인가? |
| 클라이언트가 partition-aware 해야 하나? | 클라이언트가 topology-oblivious여도 운영 가능하도록 SDK가 충분히 가려 주는가? |
| ZooKeeper 운영 비용을 어떻게 줄일까? | control plane watch/session을 Oxia로 옮겼을 때 장애 분석이 더 쉬워지는가? |
| Consumer API를 앱마다 문서로 설명해야 하나? | Queue/Stream/Checkpoint로 모델을 타입 수준에서 분리해도 팀이 혼란 없이 이행하는가? |
이건 단순 기능 추가보다 더 큰 변화다. 운영자가 다루는 추상화 수준 자체가 올라간다.
지금 당장 도입하면 안 되는 이유와, 지금 당장 실험해야 하는 이유
둘 다 맞다.
지금 당장 프로덕션에 올리면 안 되는 이유
- 릴리스 자체가 preview / not meant for production 으로 선언돼 있다.
- V5 client는 M1에서 Java 우선이다. 다언어 생태계는 GA까지 더 채워져야 한다.
- scalable topic migration은 되돌릴 수 없는 one-way 전환이다.
- PIP-460은 일부 기능이 5.0 LTS 이후로 미뤄질 수 있음을 이미 인정한다.
그래도 지금 당장 실험해야 하는 이유
- 토픽 병렬화와 ordering 문제를 푸는 방향성이 분명하다.
- 기존 regular topic에서 V5 SDK를 먼저 도입하는 migration story가 있다.
- Oxia 이행은 단순 교체가 아니라 운영 자동화 프레임워크와 함께 제안돼 검증 포인트가 명확하다.
- 구조화 로그·Gradle·jakarta 전환은 GA 직전에 급히 보면 늦다.
즉, 배포는 늦게, 학습과 검증은 지금이 맞다.
운영자 검증 체크리스트
랩 환경
- production 격리 랩 클러스터를 따로 만든다. M1은 본선 검증 대상이 아니다.
- BookKeeper, broker, metadata store 메트릭을 모두 수집해 control plane / data plane을 분리 관찰한다.
클라이언트 / 애플리케이션
- Java 소비 애플리케이션 하나를 골라
QueueConsumer또는StreamConsumer로 옮겨 본다. - 코드가
TopicMessageId,getPartitionsForTopic(),MessageRouter에 얼마나 의존하는지 먼저 inventory를 만든다. - custom plugin / interceptor가 있다면
jakarta.*전환 빌드를 별도로 검증한다.
토픽 병렬화
- key ordering이 중요한 hot topic 하나를 골라 split/merge 시나리오를 실험한다.
- migration 전후에 consumer lag, duplicate, out-of-order, replay 시간 변화를 반드시 비교한다.
- regular→scalable migrate 연산은 one-way이므로, 사전 스냅샷과 롤포워드 계획을 먼저 문서화한다.
메타데이터 이행
- ZooKeeper→Oxia rehearsal을 최소 한 번 수행한다.
PREPARATION → COPYING → COMPLETED단계별로 write path가 실제로 어떻게 제약되는지 로그와 메트릭으로 확인한다.- ephemeral node 재생성 실패, broker 재시작, partial failure 같은 비정상 경로를 일부러 넣어 본다.
관측성과 빌드 체인
PULSAR_LOG_FORMAT변경 후 기존 log collector / parser / index template가 그대로 동작하는지 본다.- 사내 포크나 패치 빌드가 있다면 CI를
mvn에서./gradlew기준으로 재검증한다. - connector를 쓰는 환경은 core와 connector의 버전 매트릭스를 따로 관리할 준비가 되어 있는지 확인한다.
정리
Apache Pulsar 5.0.0-M1의 핵심은 "새 기능이 많다"가 아니다. 파티션 중심 메시징 모델을 range-segment 중심 모델로 바꾸고, 그에 맞춰 SDK와 메타데이터 저장소를 같이 재설계한다는 선언이다.
운영자에게 의미 있는 포인트는 세 가지다.
- Scalable Topics는 파티션 수 변경이 가져오던 ordering·재배치 부담을 줄이려는 방향이다.
- V5 Client는 API가 토폴로지 세부사항을 노출하던 오래된 짐을 덜어내려 한다.
- Oxia + migration framework는 메타데이터 저장소 교체를 문서가 아니라 제품 기능으로 끌어온다.
다만 지금은 어디까지나 프리뷰다. 따라서 이 챕터의 결론은 "업그레이드하라"가 아니라 더 단순하다.
지금은 5.0의 제어면 철학을 이해하고, ordering·migration·logging·build chain 네 축을 랩에서 검증할 때다.
References
- Apache Pulsar. Apache Pulsar 5.0.0-M1 release notes. 2026-06-23. https://github.com/apache/pulsar/releases/tag/v5.0.0-M1
- Apache Pulsar Blog. Apache Pulsar 5.0.0-M1: A Preview of the Next Major Release. 2026-06-23. https://pulsar.apache.org/blog/2026/06/23/announcing-apache-pulsar-5-0-m1/
- Apache Pulsar PIP-460. Scalable Topics (Topics v5). https://github.com/apache/pulsar/blob/master/pip/pip-460.md
- Apache Pulsar PIP-466. New Java Client API (V5) with Scalable Topic Support. https://github.com/apache/pulsar/blob/master/pip/pip-466.md
- Apache Pulsar PIP-475. Regular-to-Scalable Topic Migration. https://github.com/apache/pulsar/blob/master/pip/pip-475.md
- Apache Pulsar PIP-454. Metadata Store Migration Framework. https://github.com/apache/pulsar/blob/master/pip/pip-454.md
- Apache Pulsar PIP-467. Adopt slog for structured logging across Pulsar. https://github.com/apache/pulsar/blob/master/pip/pip-467.md
- Apache Pulsar PIP-463. Migrate Build System from Maven to Gradle. https://github.com/apache/pulsar/blob/master/pip/pip-463.md