LabHub

데이터 파이프라인 · 데이터 품질과 계약 · 이론

초록불인데 숫자가 틀렸다

LabHub 에서 이어서 보기

한 줄 요약

파이프라인의 성공/실패는 데이터의 맞음/틀림과 다른 축입니다.
품질을 재지 않으면, 조용히 비어 있는 테이블 위에서 대시보드가 초록불로
켜져 있습니다.

왜 이게 필요했나

월요일 아침 회의에서 매출이 전주 대비 40% 떨어졌다는 보고가 나옵니다.
영업팀이 뒤집어집니다. 하루 종일 원인을 찾다가 오후에 밝혀집니다 —
상류 시스템이 토요일에 파일을 안 보냈고, 파이프라인은 빈 파일을
정상적으로 처리해서 0건을 적재했습니다.

파이프라인은 실패하지 않았습니다. 에러도 없고, 재시도도 없고, 알림도
없었습니다. 문제는 아무 일도 일어나지 않았다는 사실을 아무도 모른 것
입니다.

네 가지 품질 축

| 축 | 질문 | 측정 |
| --- | --- | --- |
| 신선도 (freshness) | 데이터가 언제 것인가 | 최신 레코드 시각과 현재의 차이 |
| 완전성 (completeness) | 있어야 할 만큼 있는가 | 건수, 널 비율 |
| 유일성 (uniqueness) | 중복이 없는가 | 키별 중복 건수 |
| 유효성 (validity) | 값이 규칙을 지키는가 | 범위·형식·참조 무결성 |

각각을 쿼리 한 줄로 잴 수 있습니다.

-- 신선도: 마지막 데이터가 몇 분 전인가SELECT extract(epoch from now() - max(event_at))/60 AS lag_min FROM events;-- 완전성: 어제 건수가 지난 7일 평균 대비 얼마인가WITH d AS (  SELECT date_trunc('day', event_at) AS day, count(*) AS n  FROM events WHERE event_at >= now() - interval '8 days' GROUP BY 1)SELECT (SELECT n FROM d ORDER BY day DESC LIMIT 1)::float     / NULLIF(avg(n), 0) AS ratio FROM d;-- 유일성SELECT count(*) FROM (  SELECT order_id FROM orders GROUP BY 1 HAVING count(*) > 1) x;-- 유효성SELECT count(*) FROM orders WHERE amount < 0 OR status NOT IN ('NEW','PAID','CANCELLED');

임계값은 절대값이 아니라 비율로

"건수가 1000 미만이면 알림" 같은 규칙은 곧 무용지물이 됩니다. 서비스가
자라면 임계값을 계속 고쳐야 하고, 아무도 안 고칩니다.

대신 자기 자신과 비교합니다.

요일 효과를 무시하면 월요일마다 오탐이 납니다. 주말에 트래픽이 적은
서비스에서 "어제 대비" 는 매주 월요일 오전에 거짓 경보를 냅니다.
같은 요일끼리 비교하세요.

데이터 계약

품질 검사는 사후 대응입니다. 근본은 상류와 합의하는 것입니다.

데이터 계약(data contract)은 생산자와 소비자 사이의 명시적 약속입니다.

dataset: ordersowner: order-teamschema:  order_id:   { type: string, required: true, unique: true }  amount:     { type: decimal, required: true, min: 0 }  status:     { type: enum, values: [NEW, PAID, CANCELLED] }  created_at: { type: timestamp, required: true }sla:  freshness: 30m          # 30분 이내 데이터가 있어야 함  completeness: 0.99      # 널 비율 1% 미만breaking_change: 30일 전 공지

계약이 있으면 두 가지가 달라집니다.

1. 책임 소재가 분명해집니다. "스키마가 바뀌어서 깨졌다" 가 아니라
"계약을 위반했다" 가 됩니다.
2. 자동 검증이 가능합니다. 계약 파일 자체가 검사 규칙이 됩니다.

검사를 어디에 두는가

추출 → [입력 검사] → 변환 → [출력 검사] → 적재 → [사후 검사]

가장 흔한 실수는 사후 검사만 두는 것입니다. 그러면 이미 오염된 데이터가
대시보드와 다른 파이프라인으로 퍼진 뒤에 알게 됩니다.

실패를 어떻게 다룰 것인가

검사가 실패했을 때 선택지는 셋입니다.

| 대응 | 언제 |
| --- | --- |
| 중단 (fail) | 하류가 틀린 데이터를 쓰면 안 될 때. 결제·정산 |
| 격리 (quarantine) | 일부만 문제일 때. 나쁜 행만 따로 빼고 나머지 진행 |
| 경고 (warn) | 품질이 낮아도 없는 것보다 나을 때. 탐색용 데이터 |

무조건 중단은 안 됩니다 — 사소한 문제로 전체가 멈추면 사람들이 검사를
꺼 버립니다. 무조건 경고도 안 됩니다 — 아무도 안 봅니다. 데이터셋마다
정해야 합니다.

현장에서 만나는 모습

다음 퀴즈에서 확인할 것

품질 축 네 가지를 쿼리로 구현해 실제 데이터셋에 적용하고, 요일을 고려한
상대 임계값으로 이상을 탐지합니다. 계약 위반을 만들어 검사가 잡아내는지
확인하고, 중단·격리·경고 세 가지 대응을 구분해 적용합니다.