LLM WikiAccess-protected knowledge portal

WIKI

Apache Pinot 1.5: 멀티클러스터 페더레이션과 Multi-Stage 쿼리 엔진으로 리얼타임 OLAP의 운영 경계를 다시 그은 릴리스

왜 Pinot이고 왜 1.5인가 Apache Pinot은 LinkedIn에서 시작한 사용자 대면 리얼타임 OLAP 데이터베이스다. 분석 쿼리를 초 단위가 아니라 밀리초 단위로 처리해야 하는 시나리오, 즉 "지금 이 페이지를 보는 사람의 최근 30일 행동 요약"이나 "광고 캠페인의 실시간 클릭률"처럼 수억 건 레코드를 수백 밀리초 안에 돌려줘야 하는 환경을 위해 설계됐다. 기존 접근법의 한계는 명확했다. OLTP DB MySQL

경로human/study/content/database-frontier/29-apache-pinot-1-5-federation-routing-multistage-olap.md
카테고리Study
태그#federation #infra #kubernetes #monitoring #multistage #mysql #olap #pinot #routing #study

왜 Pinot이고 왜 1.5인가

Apache Pinot은 LinkedIn에서 시작한 사용자 대면 리얼타임 OLAP 데이터베이스다. 분석 쿼리를 초 단위가 아니라 밀리초 단위로 처리해야 하는 시나리오, 즉 "지금 이 페이지를 보는 사람의 최근 30일 행동 요약"이나 "광고 캠페인의 실시간 클릭률"처럼 수억 건 레코드를 수백 밀리초 안에 돌려줘야 하는 환경을 위해 설계됐다.

기존 접근법의 한계는 명확했다.

Pinot이 이 틈새를 채운다. 2026년 4월 15일 출시된 Pinot 1.5.0은 운영자가 주목할 세 가지 구조적 변화를 담고 있다: 멀티클러스터 페더레이션 라우팅, MSE 쿼리 엔진 성숙, Upsert 운영 개선. 그리고 Kafka 4.x KRaft 지원으로 ZooKeeper 의존 고리를 하나 더 끊었다.


Pinot 아키텍처 기본

Pinot 클러스터는 네 종류의 프로세스로 구성된다.

클러스터 조정은 Apache HelixZooKeeper가 담당한다. Helix가 원하는 상태(서버 수, 세그먼트 할당 등)를 ZooKeeper에 유지하고, 각 컴포넌트가 이 상태를 지켜보며 자신의 역할을 수행한다.

세그먼트 단위로 데이터를 관리한다는 점이 핵심이다. 배치 수집은 세그먼트 파일을 만들어 딥스토어에 올리고 Controller에 알리는 방식이고, 실시간 수집은 서버가 Kafka를 직접 소비하면서 메모리에서 세그먼트를 만든다. 이 세그먼트가 커밋(flushed)되면 스토리지에 쓰이고 오프라인 세그먼트와 동일하게 관리된다.

Apache Pinot 1.5 아키텍처와 주요 변화 사용자/앱 SQL 쿼리 (밀리초 SLA) Federation Broker (1.5 신규) 단일 브로커 → 복수 Pinot 클러스터에 쿼리 라우팅 (Logical Table 기반) SSE 쿼리, MSE 쿼리 모두 멀티클러스터 라우팅 지원 Pinot 클러스터 A Broker (SSE/MSE) Controller Multi-Stage Query Engine (MSE) — 1.5 성숙 UNNEST 지원 (중첩 배열 전개) enriched joins · aggregation rewrites · Query Resource Isolation Real-Time Server Kafka 소비 → 메모리 세그먼트 Upsert 1.5: 오프라인 테이블 지원 Offline Server 배치 세그먼트 저장 commit-time compaction Pinot 클러스터 B Broker (SSE/MSE) Controller 독립 스케일링 클러스터 B는 다른 데이터셋·SLA·인프라 독립 운영 Kafka 4.x / KRaft (1.5 신규) pinot-kafka-4.0 모듈 (Kafka 4.1.1 client) KRaft 모드 — ZooKeeper 의존성 제거 파티션 서브셋 소비 (테이블이 일부 파티션만 담당) Helix + ZooKeeper (클러스터 조정) 세그먼트 할당 · 서버 상태 · 라우팅 테이블 갱신 Deep Store (S3/GCS/Azure) 오프라인·실시간 세그먼트 영구 저장 Pinot 1.5 기준 | 릴리스 2026-04-15 | 1,100+ 커밋
Apache Pinot 아키텍처와 1.5 핵심 변화

핵심 변화 1: 멀티클러스터 페더레이션 라우팅

Pinot 1.5의 가장 구조적인 변화다. 기존에는 하나의 Broker가 하나의 Pinot 클러스터 안의 서버들에게 쿼리를 분산했다. 조직이 여러 Pinot 클러스터를 운영한다면—예컨대 지역별·서비스별로 독립된 클러스터—쿼리 시에 어느 클러스터에 붙을지를 애플리케이션이 알고 있어야 했다.

1.5에서 Federation Broker가 이 책임을 가져간다. 단일 브로커 엔드포인트에 쿼리를 보내면, 브로커가 여러 Pinot 클러스터로 라우팅하고 결과를 합쳐서 반환한다.

운영 모델 변화

이 기능은 Logical Table 위에서만 동작한다. 물리 테이블(physical table)에 대한 직접 멀티클러스터 라우팅은 의도적으로 막혀 있다.

Logical Table은 Pinot 1.4에서 도입된 개념으로, 여러 물리 테이블을 하나의 논리 테이블로 묶는 레이어다. 1.5에서는 이 논리 테이블이 서로 다른 클러스터에 있는 물리 테이블을 묶을 수 있게 됐다.

이것이 열어주는 운영 시나리오는 구체적이다.

SSE(Single-Stage Engine) 쿼리와 MSE(Multi-Stage Engine) 쿼리 모두 멀티클러스터 라우팅을 지원한다.

제약


핵심 변화 2: Multi-Stage Query Engine(MSE) 성숙

Pinot의 MSE는 분산 조인, 윈도 함수, 서브쿼리 같은 복잡한 SQL을 지원하기 위해 만들어진 실행 엔진이다. 기존 SSE(Single-Stage Engine)는 단순 집계에 특화되어 있어 조인이 제한적이었다.

1.5에서 MSE에 추가된 것들:

UNNEST 지원

UNNEST 함수로 배열·중첩 컬럼을 행으로 전개할 수 있게 됐다. Pinot에는 JSON이나 배열 컬럼에 이벤트 데이터를 통째로 저장하는 패턴이 흔한데, 이를 쿼리 시점에 펼쳐야 하는 경우 지금까지는 클라이언트에서 처리해야 했다.

-- 예: 사용자당 클릭한 상품 목록을 행으로 전개
SELECT user_id, item
FROM user_events, UNNEST(clicked_items) AS t(item)
WHERE event_date = '2026-07-20'

Join 강화와 집계 재작성

이너 조인, 외부 조인의 실행 안정성이 향상됐다. 옵티마이저가 집계 연산을 더 효율적인 형태로 재작성(aggregation rewrite)하는 경우가 늘었다.

쿼리 리소스 격리(Query Resource Isolation)

쿼리별로 메모리 한도와 실행 우선순위를 설정할 수 있게 됐다. 특정 대쿼리가 서버 메모리를 독점하는 문제를 제어하는 수단이다.


Upsert 운영 개선

Pinot의 Upsert는 기존 레코드를 새 레코드로 갱신하는 기능이다. 리얼타임 집계에 특화된 Pinot에 "갱신"이 필요한 이유는 이벤트 수정·삭제·중복 제거 같은 실운영 요구사항 때문이다.

1.5에서 Upsert에 두 가지 중요한 변화가 있다.

오프라인 테이블 지원

이전까지 Upsert는 리얼타임 테이블에서만 동작했다. 1.5부터는 오프라인 테이블(배치 수집 테이블)에서도 Upsert가 가능하다.

이것이 열어주는 운영 시나리오: 기존에 잘못 수집된 배치 데이터를 수정하거나, 배치로 들어온 레코드를 기준으로 최신 상태를 유지하는 워크로드.

commit-time compaction과 xxhash 압축

Upsert를 쓰면 같은 primaryKey의 여러 버전이 다른 세그먼트에 분산된다. 쿼리 시에 이 버전들을 비교해 최신 값을 선택하는 비용이 누적된다.

Commit-time compaction은 세그먼트가 커밋될 때 중복 레코드를 정리해서 이 비용을 미리 줄인다. xxhash 기반 레코드 해시는 중복 탐지 속도를 높인다.


Kafka 4.x KRaft 지원

Pinot 1.5는 새 pinot-kafka-4.0 모듈을 추가했다. Kafka 4.1.1 클라이언트 기반이며, KRaft 모드를 완전히 지원한다. 이는 Pinot 수집 경로에서 Kafka ZooKeeper 의존성이 사라진다는 뜻이다.

실무적으로 Kafka 클러스터를 KRaft로 이미 마이그레이션했거나 마이그레이션 계획이 있다면, Pinot 수집 쪽도 같이 업그레이드해야 한다. 기존 Kafka 3.x 연결은 이전 모듈로 계속 동작한다.

추가로 테이블이 특정 파티션만 소비할 수 있게 됐다. 하나의 Kafka 토픽을 여러 Pinot 테이블이 나눠 담당하는 분할 수집 패턴이 가능해진다.


새 인덱스 타입

1.5에서 추가된 인덱스 타입:

인덱스용도
N-gram 인덱스부분 문자열 검색 성능 개선
IFST(Inverted Finite State Transducer) 인덱스정규식·와일드카드 검색 최적화
Combined Lucene 인덱스텍스트·숫자 혼합 검색 단일 인덱스로 통합

Pinot을 도입할 때 판단 기준

Pinot은 강력하지만 도입 기준을 먼저 명확히 해야 한다.

Pinot이 맞는 경우

Pinot이 맞지 않는 경우


1.5 도입 체크리스트


한 문장으로

Pinot 1.5는 멀티클러스터 페더레이션으로 독립 운영과 통합 조회를 양립시키고, MSE 성숙으로 복잡 SQL의 실용 범위를 넓히며, Upsert와 Kafka 4 KRaft 지원으로 운영 의존성을 하나씩 정리한 릴리스다.

References