Apache Iceberg 기반 lakehouse를 구성하다 보면 "catalog를 뭘 쓸 것인가"가 계속 따라온다.
Hive Metastore나 AWS Glue로 시작하지만, 멀티 엔진 환경이 되면 결국 한계를 만난다.
이걸 해결하는 게 Apache Polaris다.
그래서 Polaris가 뭔지, 어떻게 동작하는지 정리해본다.
Apache Polaris는 Apache Iceberg를 위한 REST 기반 오픈소스 catalog 서버다.
Snowflake와 Dremio가 공동 개발해 2024년 6월 오픈소스로 공개했고, Apache Software Foundation에 기증해 2026년 2월 Top-Level Project로 졸업했다.
Spark, Flink, Trino, Dremio 등 다양한 쿼리 엔진이 단일 catalog를 통해 동일한 Iceberg 테이블에 접근할 수 있게 해준다.
Iceberg 테이블을 사용하려면 "현재 metadata 파일의 위치"를 어딘가에 저장해야 한다.
이걸 catalog가 담당한다.
기존 catalog들이 가진 문제는 다음과 같다.
| catalog | 문제점 |
|---|---|
| Hive Metastore | 멀티 엔진 지원 약함, REST API 없음, 확장성 한계 |
| AWS Glue | AWS 종속, 벤더 lock-in |
| JDBC Catalog | 멀티 엔진 concurrent access에서 안전성 문제 |
2022년 Iceberg 0.14.0에서 Iceberg REST Catalog API가 도입됐다.
표준 REST 인터페이스를 정의해두면, 어떤 catalog 구현체든 동일한 클라이언트로 통신할 수 있다.
Polaris는 이 REST Catalog spec을 완전히 구현한 서버다.
Query Engine (Spark / Flink / Trino / Dremio)
|
| Iceberg REST API (OAuth2)
↓
┌─────────────┐
│ Polaris │ ← REST Catalog 서버 (Quarkus JVM 애플리케이션)
│ Server │
└──────┬──────┘
│ metadata 저장
↓
Persistence Layer (PostgreSQL / MySQL / CockroachDB)
│
│ Credential Vending (단기 토큰 발급)
↓
Object Storage (S3 / GCS / ADLS)
Polaris 자체는 stateless한 REST 서버다.
metadata는 외부 DB에 저장하고, 실제 데이터는 오브젝트 스토리지에 있다.
Polaris는 두 종류의 catalog를 지원한다.
| 구분 | Internal Catalog | External Catalog |
|---|---|---|
| 스토리지 관리 | Polaris가 직접 관리 | 외부 시스템이 관리 |
| 테이블 위치 제어 | Polaris가 강제 | 외부 경로 그대로 등록 |
| 적합한 경우 | 신규 데이터 적재 | 기존 S3 데이터 연동 |
| Credential Vending | 기본 활성화 | 설정 필요 |
Internal catalog는 Polaris가 테이블 위치를 {warehouse_location}/{namespace}/{table} 구조로 강제한다.
External catalog는 이미 존재하는 S3 경로의 Iceberg 테이블을 그대로 등록할 수 있다.
Polaris Instance
└── Catalog (스토리지 타입 연결: S3 / GCS / ADLS)
└── Namespace (중첩 가능)
├── Table (Iceberg 테이블)
└── View (논리 뷰)
Catalog는 특정 스토리지(S3, GCS 등)와 1:1로 연결된다.
Namespace는 논리적 그룹이며, 중첩이 가능해서 db.schema.table 형태의 계층도 표현할 수 있다.
쿼리 엔진이 Polaris에 접근하려면 Service Principal이 필요하다.
Polaris는 각 Service Principal에 대해 Client ID / Client Secret 쌍을 발급하고,
엔진은 이걸로 OAuth2 토큰을 받아 REST API를 호출한다.
# Spark에서 Polaris 연결 예시
spark = SparkSession.builder \
.config("spark.sql.catalog.polaris", "org.apache.iceberg.spark.SparkCatalog") \
.config("spark.sql.catalog.polaris.type", "rest") \
.config("spark.sql.catalog.polaris.uri", "http://polaris-server:8181/api/catalog") \
.config("spark.sql.catalog.polaris.credential", "<client_id>:<client_secret>") \
.config("spark.sql.catalog.polaris.warehouse", "<catalog_name>") \
.getOrCreate()
Polaris의 핵심 보안 기능이다.
기존 방식에서는 Spark job이 S3에 직접 접근하려면 IAM 키나 Role을 job에 직접 부여해야 했다.
이 방식의 문제는 다음과 같다.
1. Trino → Polaris: "prod.warehouse.users 테이블 읽고 싶음"
2. Polaris: RBAC 권한 확인
3. Polaris → AWS STS: 해당 S3 경로에 한정된 단기 토큰 요청
4. Polaris → Trino: 단기 scoped 토큰 반환 (예: 15분 유효)
5. Trino → S3: 해당 토큰으로 Parquet 파일 읽기
Polaris는 long-lived IAM 키를 엔진에 직접 나눠주지 않는다.
대신 매 요청마다 해당 테이블 경로에만 유효한 단기 토큰을 동적으로 발급한다.
AWS에서는 STS AssumeRole로 scoped inline policy를 생성하는 방식으로 동작한다.
Polaris는 2계층 RBAC 모델을 사용한다.
Principal (Service Principal)
└── Principal Role (identity 계층)
└── Catalog Role (permission 계층)
└── Privileges (catalog / namespace / table 단위)
이 분리 덕분에 identity 관리와 permission 관리가 독립적이다.
Spark job과 Dremio 쿼리가 같은 테이블에 접근하더라도, 동일한 access control 레이어를 통과한다.
외부 policy 시스템(OPA, Open Policy Agent)과의 통합도 지원해, 조직 내 기존 policy 프레임워크를 연결할 수 있다.
2025년 10월 릴리즈된 v1.1에서 Catalog Federation이 추가됐다.
Polaris (main catalog)
├── Internal Catalog
├── Federated Catalog A (Snowflake Horizon)
└── Federated Catalog B (AWS Glue)
단일 Polaris 인스턴스가 중심 catalog 역할을 하면서,
그 아래에 다른 catalog들을 federated 형태로 연결할 수 있다.
Implicit 인증 타입도 추가됐는데, federated catalog에 인증할 때 Polaris가 credential을 직접 저장하지 않고 환경 변수나 설정 파일을 통해 전달할 수 있다.
| Apache Polaris | Unity Catalog | Nessie | |
|---|---|---|---|
| 오픈소스 | ✅ Apache TLP | ✅ Apache 2.0 | ✅ Apache 2.0 |
| Iceberg REST spec | ✅ Native | 부분 지원 | ❌ |
| 지원 포맷 | Iceberg + Delta/Hudi (read) | Iceberg / Delta / Hudi | Iceberg only |
| Credential Vending | ✅ | ❌ | ❌ |
| Git-style branching | ❌ | ❌ | ✅ |
| Lineage | 제한적 | ✅ | ❌ |
| AI asset 관리 | 미지원 | ✅ | ❌ |
| 자체 배포 | ✅ | 제한적 | ✅ |
| 강점 | 멀티엔진 / 벤더 중립 | Databricks 생태계 | Git 워크플로우 |
| 상황 | 선택 |
|---|---|
| Spark + Flink + Trino 멀티 엔진 환경 | ✅ Polaris |
| 특정 클라우드나 벤더에 종속되고 싶지 않음 | ✅ Polaris |
| Long-lived S3 키 없이 안전한 데이터 접근 | ✅ Polaris |
| 기존 Iceberg 데이터를 catalog에 등록만 하고 싶음 | ✅ Polaris (External Catalog) |
| Databricks 중심 환경 | Unity Catalog |
| 데이터 CI/CD, 브랜치 기반 실험 | Nessie |
| Spark 단일 엔진 + 단순한 workload | Hive Metastore / Glue로도 충분 |
| 버전 | 주요 변화 |
|---|---|
| 2024.06 | Snowflake + Dremio가 오픈소스로 공개 |
| 2024.08 | Apache Software Foundation 기증, Incubator 입합 |
| 1.0 (2025.07) | 최초 공식 릴리즈 |
| 1.1 (2025.10) | Catalog Federation, Implicit 인증, CLI 업데이트 |
| TLP (2026.02) | Apache Top-Level Project 졸업 |