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 무력화)
MERGEappend 대신 “테이블이 이 데이터셋을 반영하게” — 단, 소스 dedup 선행 필수
동적 파티션 overwrite배치 케이스의 가장 깔끔한 primitive — 재실행이 파티션 교체
watermark dedup스트리밍 — 시간 윈도우 내만 dedup해 state 무한 증가 방지
Kafka idempotent producerenable.idempotence=true로 broker가 retry 중복 drop; transaction으로 multi-partition atomic
receiver idempotency keywrite를 소유 못할 때 — 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규칙

  1. logical execution date로 파티션(ds), 절대 datetime.now() 아님 — 월요일 실패를 화요일에 재실행해도 월요일 데이터 타깃
  2. 입력을 immutable로 취급 — mutable upstream은 “누가 source 건드리기 전까지만 멱등”
  3. 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 멱등성.

연관 개념


Source: Idempotency in Data Engineering