전체 그래프
Concepts

Medallion Architecture

data-engineeringlakehousemedallionarchitecture

상위: Lakehouse Architecture

요약

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

세 계층

Medallion Architecture

데이터 소스  [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()

계층 간 비교

항목BronzeSilverGold
데이터 품질원본 그대로정제, 검증됨비즈니스 로직 적용
스키마Schema-on-ReadSchema-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: 계층 간 품질 계약

참고 자료