본문 바로가기
C.W.K.
Stream
Lesson 06 of 06 · published

실전 Idempotency

~11 min · idempotency, production, patterns

Level 0구경꾼
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

파이프라인이 가질 수 있는 속성 중 제일 값진 것

Idempotent 파이프라인은 한 번을 돌리든, 두 번이든, 스무 번이든 같은 결과를 만들어. 이 속성이 생기는 순간 디버깅이 더는 무섭지 않아 — "그냥 다시 돌려" 가 희망 섞인 기도가 아니라 진짜 답이 되거든. 없으면? Retry 할 때마다 주사위를 굴리는 거야.

파이프라인을 idempotent 하게 만드는 네 가지 실전 패턴

  1. Raw lake 에선 path 에 불변성을 새겨. raw/orders/2026/04/30/run_20260430120000.json.gz — run timestamp 가 path 자체에 들어가. 두 번째 run 은 옆자리에 새 파일을 쓰고, downstream stage 는 사전순 최신을 읽어.
  2. 분석 테이블에선 partition replace. warehouse/orders/date=2026-04-30/. 다시 돌리면 그 partition 을 통째로 갈아 끼워 (stage 하고 swap — lesson 3 에서 뜯어본 그 복구 가능한 두-rename 순서로).
  3. OLTP 모양 목적지엔 primary key 로 upsert. INSERT ... ON CONFLICT (order_id) DO UPDATE. 같은 key 는 덮어써지고, 다시 돌린 run 은 결과적으로 no-op 이야.
  4. 데이터가 아닌 side effect — 이메일, 웹훅, 알림 — 엔 dedup key. "2026-04-30 의 Q1 매출 임계 알림" 같은 key 와 추적 테이블 하나면 돼.

Code

Idempotent 알림 sender — 보낸 key 추적해서 dedup·python
import sqlite3

def maybe_send_alert(conn: sqlite3.Connection, key: str, body: str) -> bool:
    '''키당 최대 한 번 알림 보냄. 보냈으면 True.'''
    cur = conn.execute('SELECT 1 FROM sent_alerts WHERE key = ?', (key,))
    if cur.fetchone() is not None:
        return False

    send_email(body)                                          # side effect
    conn.execute('INSERT INTO sent_alerts(key, sent_at) VALUES (?, datetime("now"))', (key,))
    conn.commit()
    return True

# 둘러싼 파이프라인이 다섯 번 돌아도 알림은 한 번만
maybe_send_alert(conn, key='q1-revenue-2026-04-30', body='Q1 매출 12% 하락')

External links

Exercise

본인이 쓴 파이프라인 (또는 스케줄 스크립트) 하나 골라. Side effect 하나하나 — 파일 write, DB insert, 이메일 send, API call — 가 idempotent 인지 점수를 매겨 봐. 제일 위험한 것 하나에 대해 idempotent 하게 만들 방법 (path 에 새기기, partition replace, upsert, dedup 테이블) 을 스케치해. 오늘 고치지 않아도 돼 — 진단만으로도 배우는 게 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.