950 words
5 minutes
[DE Design Pattern]02-1. Full Load
Pattern Overview
- Full Load → 전체 교체, View Switching으로 일관성 확보
- Incremental Load → Delta Column / Partition 기반 증분, Ingestion Window로 백필 안전성
- CDC → 커밋 로그 기반 실시간 캡처, Data in Motion 의미론 주의
- Replication → Passthrough(단순 복사) vs Transformation(PII 처리), Keep It Simple
- Compaction → Small Files 해결, OPTIMIZE + VACUUM 세트, Kafka는 의미가 다름
- Readiness & Trigger → Flag File / Convention으로 완성, External Trigger로 이벤트 기반 수집
01. Full Load Pattern
전체 교체 패턴
Drop-and-Insert의 문제
- 클라이언트 관점의 데이터 일관성 : DROP과 INSERT 사이에 쿼리하면 데이터가 없거나 부분적으로만 보임. 트랜잭션을 지원하는 DB일 경우 트랜잭션으로 감쌀 수 있지만, 아닐 경우 별도 전략이 필요
- 롤백 불가능 — 덮어쓰면 이전 버전으로 되돌릴 수 없음. Delta Lake나 Apache Iceberg 같은 Time Travel 지원 포맷이 아니라면, 직접 버전 관리를 구현해야 함
Single Data Exposition Abstraction
- 클라이언트가 보는 것(View)과 실제 데이터가 적재되는 것(물리 테이블)을 분리
- 물리 테이블 두 개(
table_1,table_2)를 번갈아 사용하고, Public View는 항상 둘 중 하나만 가리킴. 새 데이터를 현재 사용하지 않는 테이블에 적재한 뒤, View의 참조를 스위칭함.
->
- 클라이언트는는 항상 완전한 데이터를 보게됨
- 이전 버전 테이블도 남아있어 롤백이 가능
import psycopg2
def full_load_with_view_switching(conn, version: str, data_path: str): """ Single Data Exposition Abstraction 패턴 """ versioned_table = f"devices_{version}" # devices_v2
with conn.cursor() as cur: # 1) 버전 테이블 생성 cur.execute(f""" CREATE TABLE IF NOT EXISTS {versioned_table} ( device_id VARCHAR(50), device_type VARCHAR(100), full_name VARCHAR(200) ) """)
# 2) 데이터 적재 (COPY : bulk load) cur.execute(f""" COPY {versioned_table} FROM '{data_path}' WITH (FORMAT csv, HEADER true) """)
# 3) View 스위칭 cur.execute(f""" CREATE OR REPLACE VIEW devices AS SELECT * FROM {versioned_table} """)
conn.commit()핵심은 CREATE OR REPLACE VIEW가 atomic 하다는 것
Time Travel을 통한 버전 관리
- Delta Lake나 Apache Iceberg를 사용할 경우 수동 버전 관리가 불필요.
- 포맷 자체가 커밋 로그를 관리하므로
overwrite모드로 써도 이전 버전을 조회가능
# Delta Lake — Full Load + 내장 Time Travelinput_data = spark.read.schema(input_data_schema).json(input_path)input_data.write.format("delta").mode("overwrite").save("s3://master/devices")
# 문제 발생 시 이전 버전 조회previous_version = ( spark.read.format("delta") .option("versionAsOf", 0) # 첫 번째 버전 .load("s3://master/devices"))- 이 경우
overwrite를 해도 Delta Lake의 트랜잭션 로그가 이전 스냅샷을 보존 - View 스위칭 없이도 일관성과 롤백을 모두 확보 가능
Auto-scaling
- Full Load는 매번 전체를 가져오므로, 데이터 볼륨이 급증하면 정적 리소스로는 처리가 실패할 수 있음. ex) 하루 만에 데이터가 2배로 늘면 기존 배치 잡이 타임아웃될 수있음.
- 이를 대비해 데이터 처리 레이어의 auto-scaling 기능을 활용하는 것이 권장됨
Concept
- Full Load : 매 실행마다 전체 데이터셋을 교체하는 수집 패턴. 변경 감지 컬럼이 없는 소규모 참조 데이터에 적합
- Single Data Exposition Abstraction : 소비자에게 노출되는 View와 실제 물리 테이블을 분리하여, 적재 중에도 데이터 일관성과 롤백을 보장하는 패턴
- View Switching : 두 물리 테이블을 번갈아 사용하고 View 참조를 원자적으로 전환하는 기법
- Time Travel : Delta Lake, Apache Iceberg 등이 제공하는 기능으로, 데이터의 이전 버전을 커밋 로그 기반으로 조회할 수 있는 기능
- Drop-and-Insert : 기존 테이블을 삭제 후 재삽입하는 방식. 동시성 문제와 롤백 불가 문제를 유발
- Passthrough Job : 데이터가 변환 없이 소스에서 목적지로 단순 통과하는 EL 작업
[DE Design Pattern]02-1. Full Load
https://yjinheon.netlify.app/posts/02de/de-design-pattern/02-data-ingestion/02-di-01-full_load/