요약
Medallion Architecture는 Lakehouse에서 데이터를 Bronze → Silver → Gold 세 계층으로 조직하는 패턴이다. 각 계층을 거칠수록 데이터 품질이 점진적으로 향상되며, ELT 방식으로 먼저 적재한 후 변환한다. Databricks가 대중화했지만 벤더에 종속되지 않는 범용적인 설계 패턴이다.
세 계층

데이터 소스 → [Bronze] → [Silver] → [Gold] → BI / ML / 분석
(원본) (정제) (비즈니스)
Bronze Layer (Raw)
원본 데이터를 있는 그대로 저장한다.
- Append-only 방식으로 수집
- 스키마 변환 없이 원본 그대로 보존
- 메타데이터 추가: 수집 타임스탬프, 소스 ID, 배치 ID 등
- 데이터 리니지(lineage)의 출발점
- 문제 발생 시 원본에서 재처리 가능
# Bronze: Kafka에서 원본 그대로 적재
bronze_df = (
spark.readStream
.format("kafka")
.option("subscribe", "orders")
.load()
.selectExpr(
"CAST(value AS STRING) as raw_data",
"topic",
"partition",
"offset",
"timestamp as kafka_timestamp",
"current_timestamp() as ingested_at"
)
)
bronze_df.writeStream \
.format("iceberg") \
.outputMode("append") \
.toTable("catalog.bronze.orders_raw")
저장 포맷: JSON, Avro, CSV 등 원본 그대로. 또는 Parquet으로 변환하되 내용은 변경하지 않음.
Silver Layer (Curated / Cleaned)
정제되고 구조화된 데이터. "신뢰할 수 있는 진실의 원천(Single Source of Truth)".
- 중복 제거 (deduplication)
- 데이터 타입 변환 및 표준화
- NULL 처리, 유효성 검증
- 스키마 적용 (Schema Enforcement)
- 테이블 간 조인으로 관계 정립
- PII 마스킹, 데이터 품질 체크
# Silver: Bronze에서 읽어 정제
from pyspark.sql.functions import from_json, col, schema_of_json
# 스키마 적용
order_schema = "order_id STRING, user_id STRING, amount DOUBLE, status STRING, created_at TIMESTAMP"
silver_df = (
spark.read.table("catalog.bronze.orders_raw")
.select(from_json(col("raw_data"), order_schema).alias("data"), "ingested_at")
.select("data.*", "ingested_at")
# 중복 제거
.dropDuplicates(["order_id"])
# NULL 필터링
.filter(col("order_id").isNotNull())
# 타입 검증
.filter(col("amount") >= 0)
)
silver_df.writeTo("catalog.silver.orders") \
.using("iceberg") \
.createOrReplace()
Gold Layer (Business / Aggregated)
비즈니스 로직이 적용된 분석용 데이터. 특정 유스케이스에 최적화.
- 비즈니스 규칙에 따른 집계 (일별 매출, 월별 사용자 수 등)
- KPI 계산
- 도메인별 데이터 마트
- BI 대시보드, ML 피처용 데이터셋
- 특정 시간/지역 등으로 필터링된 뷰
# Gold: 일별 매출 집계
gold_daily_revenue = (
spark.read.table("catalog.silver.orders")
.filter(col("status") == "delivered")
.groupBy(
col("created_at").cast("date").alias("order_date")
)
.agg(
count("order_id").alias("total_orders"),
sum("amount").alias("total_revenue"),
avg("amount").alias("avg_order_value")
)
)
gold_daily_revenue.writeTo("catalog.gold.daily_revenue") \
.using("iceberg") \
.createOrReplace()
계층 간 비교
| 항목 | Bronze | Silver | Gold |
|---|---|---|---|
| 데이터 품질 | 원본 그대로 | 정제, 검증됨 | 비즈니스 로직 적용 |
| 스키마 | Schema-on-Read | Schema-on-Write | 도메인별 스키마 |
| 중복 | 있을 수 있음 | 제거됨 | 없음 |
| 사용자 | 데이터 엔지니어 | 데이터 엔지니어, 분석가 | 비즈니스 분석가, ML |
| 보존 기간 | 장기 보존 | 중기 | 단기~중기 |
| 변환 비용 | 없음 | 중간 | 높음 |
설계 원칙 & Best Practices
ELT, ETL이 아니다
Lakehouse + Medallion에서는 ELT가 표준이다.
- Load first (Bronze): 원본을 빠르게 적재하여 소스 시스템과 커플링 최소화
- Transform later (Silver, Gold): Lakehouse 내에서 탄력적인 컴퓨팅으로 변환
독단적으로 적용하지 말 것
Medallion은 유용한 사고 모델이지만 모든 경우에 세 계층이 필요한 건 아니다.
- 단순한 파이프라인은 Bronze → Gold로 충분할 수 있다
- 데이터 소스, 팀 워크플로우, 운영 제약에 맞게 조정한다
Data Mesh와의 결합
2025-2026년 트렌드로, Medallion의 데이터 조직 패턴과 Data Mesh의 도메인 소유권을 결합하는 사례가 늘고 있다.
[주문 도메인] [사용자 도메인]
Bronze → Silver → Gold Bronze → Silver → Gold
(주문 팀 소유) (사용자 팀 소유)
각 도메인 팀이 자신의 Medallion 파이프라인을 소유하고, Gold 레이어를 "데이터 프로덕트"로 외부에 제공한다.
데이터 품질 게이트
각 계층 전환 시 품질 검증을 넣는 것이 좋다.
- Bronze → Silver: NULL 체크, 스키마 검증, 중복 탐지
- Silver → Gold: 비즈니스 규칙 검증, 볼륨 이상 탐지
- 도구: Great Expectations, Soda, dbt tests
관련 개념
- Lakehouse Architecture: Medallion이 적용되는 상위 아키텍처
- Apache Iceberg: Medallion 구현에 사용되는 테이블 포맷
- Delta Lake: Medallion을 대중화한 테이블 포맷
- Data Mesh: 도메인 중심 아키텍처와의 결합
- Data Contract: 계층 간 품질 계약