Idempotency
1번 실행하든 100번 실행하든 같은 최종 상태 — 분산 데이터 파이프라인의 조용한 안전장치
핵심 개념
Idempotency(멱등성)는 연산이 한 번 실행되든 여러 번 실행되든 동일한 최종 상태를 만드는 성질이다. SET balance = 100은 멱등, balance = balance + 50은 아니다. 분산 시스템은 by design 재시도하므로, 모든 write를 설계할 때 두 가지를 물어야 한다: 키가 무엇이고, 두 번 실행되면 어떻게 되나?
exactly-once와 혼동 금지: exactly-once는 전달·처리 보장(비싸고 fragile, 경계에서 종종 불가능)이고, idempotency는 더 싸고 정직한 대안 — 세상이 각 메시지를 한 번 전달하도록 강제하는 대신, write를 중복 적용에 관대하게 만든다.
왜 분산 시스템이 naive 파이프라인을 깨는가
4계층이 중복을 유발한다:
- 브로커(Kafka/SQS/PubSub): at-least-once — offset commit 직전 장애 시 재전달
- 컴퓨트(Spark): speculative execution + 기본 4회 재시도 → 관리 안 된 side effect는 여러 번 실행
- 오케스트레이터(Airflow): clear & retry, 백필이 history 재실행
- 스토리지: write가 atomic 아님 — 1,000 파일 중 800개 남기고 crash 시 재시도가 1,000개 다시 씀
멱등 write 패턴
| 패턴 | 핵심 |
|---|---|
| 결정론적 키 | natural key 또는 immutable 필드 hash. 절대 now()/random UUID 아님(재시도 시 변해서 dedup 무력화) |
| MERGE | append 대신 “테이블이 이 데이터셋을 반영하게” — 단, 소스 dedup 선행 필수 |
| 동적 파티션 overwrite | 배치 케이스의 가장 깔끔한 primitive — 재실행이 파티션 교체 |
| watermark dedup | 스트리밍 — 시간 윈도우 내만 dedup해 state 무한 증가 방지 |
| Kafka idempotent producer | enable.idempotence=true로 broker가 retry 중복 drop; transaction으로 multi-partition atomic |
| receiver idempotency key | write를 소유 못할 때 — Stripe식 키로 재시도를 receiver의 no-op으로 |
Medallion별 멱등성 (Medallion Architecture)
- Bronze: raw·append-only·immutable. dedup 안 함. 멱등 보장은 replay 안전(offset/file path 키로 re-read가 append 아닌 overwrite)
- Silver: 완전 dedup의 battleground. 결정론적 키·watermark·MERGE가 실행 — accidental 재실행을 harmless non-event로 바꾸는 circuit breaker. 하나만 hardening한다면 여기
- Gold: date/grain 단위 완전 overwrite.
+= counter금지 — 재실행이 동일 메트릭 생성해야
오케스트레이션 3규칙
- logical execution date로 파티션(
ds), 절대datetime.now()아님 — 월요일 실패를 화요일에 재실행해도 월요일 데이터 타깃 - 입력을 immutable로 취급 — mutable upstream은 “누가 source 건드리기 전까지만 멱등”
- output path를 입력의 pure function으로 —
latest/나 random timestamp 금지, logical date를 path에 인코딩
증명: 가정하지 말고 테스트하라
run-twice 테스트(같은 입력으로 두 번 실행, 상태 동일 assert). 내용 hash 비교(row count 아님 — 유효 행 삭제 + 중복 추가로 count 동일할 수 있음). property-based 테스트로 중복·지각·순서뒤바뀜 batch 생성.
거버넌스·보안·관측성도 멱등성에 의존
- lineage: 결정론적·replayable 변환이면 gold 숫자를 input에서 재구성 가능(non-idempotent는 “어디서 왔나”에 답 없음)
- GDPR 삭제: “이 데이터가 absent하게”는 구조적으로 멱등 연산
- 관측성: 2배 주문 수는 canonical observability miss — volume anomaly check + 멱등 파이프라인이면 fix가 “해당 파티션 재실행”
트레이드오프
MERGE는 append보다 느리고 비쌈, 스트리밍 dedup state는 메모리 비용. 비즈니스의 중복 비용 < 방지 엔지니어링 비용일 때만 calibrate. append-only 이벤트 로그(다운스트림이 dedup)는 raw append OK, best-effort 메트릭은 at-least-once 수용. 돈·billing·재고·규제는 strict 멱등성.
연관 개념
- Silent Failures and Data Integrity — 멱등성 결여가 만드는 조용한 중복
- Medallion Architecture — 레이어별 멱등 보장
- Change Data Capture — at-least-once 전달과 dedup
- Catalog-Managed Tables — MERGE/CoW/MoR로 멱등 write
- Data Pipeline Fundamentals — 백필·재실행 안전성
- Workflow Orchestration — logical date 기반 재실행
Source: Idempotency in Data Engineering