이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • 데이터 품질 이상을 freshness, completeness, accuracy 중 무엇으로 먼저 분류해야 하는가?
  • source, pipeline, mart, dashboard 중 어느 층의 문제인지 어떤 순서로 확인하는가?
  • 품질 이상이 사용자 의사결정에 영향을 줄 때 어떤 완화 조치를 먼저 해야 하는가?
  • 복구 후 rule, alert, owner, runbook을 어떻게 바꿔야 재발을 줄일 수 있는가?

개요

데이터 품질 이상은 API 장애처럼 명확하게 드러나지 않을 때가 많다.

대시보드 수치가 0이거나, 검색 결과가 오래됐거나, 추천 feature가 비어 있어도 API status는 200일 수 있다.

품질 이상 대응의 첫 단계는 원인 추정이 아니라 어떤 품질 차원이 깨졌는지 분류하는 것이다.

첫 분류

분류질문예시
freshness최신 데이터가 들어왔는가?mart 최신 시간이 3시간 전
completeness들어와야 할 row가 빠졌는가?source 10만 건, mart 8만 건
accuracy값이나 집계가 맞는가?매출 합계가 source와 5% 차이
validity값 형식과 범위가 맞는가?unknown enum, null key
consistencydataset끼리 같은 말을 하는가?finance mart와 dashboard 금액 불일치

분류가 틀리면 runbook도 틀린다.

freshness 문제에 accuracy 검증만 반복하면 복구가 늦어진다.

확인 순서

품질 이상을 발견하면 다음 순서로 본다.

  1. 사용자 또는 의사결정 영향이 있는가?
  2. 어떤 dataset, partition, metric이 문제인가?
  3. source DB 또는 source event는 정상인가?
  4. pipeline run은 성공했는가?
  5. consumer lag, batch failure, transform error가 있는가?
  6. target mart, index, feature가 최신인가?
  7. dashboard query나 cache 문제가 아닌가?
  8. 품질 rule은 왜 먼저 잡지 못했는가?

이 순서는 source에서 target으로 이동하는 데이터 흐름을 따라간다.

완화 조치

잘못된 데이터가 사용 중이면 복구보다 공개 제어가 먼저일 수 있다.

  • dashboard에 stale 또는 invalid banner를 표시한다.
  • 정산, 리포트 export, 자동 의사결정을 잠시 중단한다.
  • 추천 feature를 이전 정상 snapshot으로 fallback한다.
  • 검색 결과에서 삭제 누락 위험 항목을 숨긴다.
  • 관련 팀에 영향 범위와 예상 복구 시간을 알린다.

품질 장애는 틀린 데이터가 계속 사용될 때 비용이 커진다.

Source 확인

SELECT count(*) AS rows,
       max(updated_at) AS newest_update,
       sum(paid_amount) AS paid_amount
FROM orders
WHERE paid_at >= date '2026-06-30'
  AND paid_at <  date '2026-07-01';

source가 이미 틀렸다면 백엔드 domain logic, migration, event 발행 조건을 확인한다.

source가 맞다면 pipeline과 target을 본다.

Pipeline 확인

SELECT job_name, run_id, status, target_from, target_to, error_message
FROM batch_job_runs
WHERE target_from >= date '2026-06-30'
ORDER BY started_at DESC;
SELECT consumer_group, topic, max_lag, dlt_count, checked_at
FROM consumer_group_health
WHERE topic = 'order-paid'
ORDER BY checked_at DESC
LIMIT 10;

pipeline이 성공으로 끝났어도 transform logic이 잘못되면 accuracy가 깨진다.

그래서 job status와 quality rule을 함께 봐야 한다.

Target 검증

SELECT 'source' AS side, count(*) AS rows, sum(paid_amount) AS amount
FROM orders
WHERE paid_at >= date '2026-06-30'
  AND paid_at <  date '2026-07-01'
UNION ALL
SELECT 'mart' AS side, count(*) AS rows, sum(paid_amount) AS amount
FROM mart_order_daily
WHERE order_date = date '2026-06-30';

row 수, 합계, 최신 시각, null 비율, enum 분포를 같이 본다.

하나의 count만 맞는다고 품질이 맞는 것은 아니다.

장애 기록

incident: dq-order-daily-20260630
dimension: accuracy
dataset: mart_order_daily
partition: 2026-06-30
detected_by: finance analyst
impact: settlement dashboard exposed wrong paid amount
source_status: source orders amount correct
pipeline_status: transform missed PARTIAL_REFUND
mitigation: dashboard banner + export pause
recovery: fix mapping, backfill 2026-06-30
validation: source amount = mart amount, rule passed
follow_up: add refund reason distribution rule

기록에는 어떤 차원의 품질 이상인지와 검증 결과가 남아야 한다.

재발 방지

복구 후에는 다음 중 하나 이상이 바뀌어야 한다.

  • source contract 문서.
  • integration event schema와 compatibility test.
  • quality rule SQL.
  • alert severity와 owner.
  • runbook의 확인 쿼리.
  • 기능 PR의 데이터 영향 체크리스트.

아무것도 바뀌지 않으면 같은 품질 이상이 다시 발생한다.

운영 지표

  • detected_by_user_count: 사용자가 먼저 발견한 품질 이상 수.
  • freshness_breach_count: freshness SLA 위반 수.
  • completeness_diff_ratio: source-target row 차이 비율.
  • accuracy_diff_ratio: source-target 금액 또는 metric 차이 비율.
  • rule_coverage_gap_count: 장애 후 누락된 rule로 확인된 항목 수.

품질 runbook의 목표는 장애 수를 0으로 만드는 것이 아니라 늦은 감지와 반복 장애를 줄이는 것이다.

위험 신호!

  • 품질 이상을 freshness, completeness, accuracy로 분류하지 않는다.
  • 대시보드 문제라고 단정하고 source와 pipeline을 확인하지 않는다.
  • API가 정상이라는 이유로 데이터 장애를 낮은 우선순위로 둔다.
  • 복구 후 rule과 alert가 추가되지 않는다.
  • 사용자 보고가 자동 rule보다 빠른 상황이 반복된다.

확인 질문

확인 질문

  • freshness와 accuracy를 구분하지 않으면 어떤 잘못된 대응을 하게 되는가?
  • source가 맞고 target이 틀렸다면 어떤 계층을 확인해야 하는가?
  • 품질 이상에서 공개 중단이나 banner가 필요한 이유는 무엇인가?
  • 회고 후 quality rule이 추가되지 않으면 어떤 리스크가 남는가?

참고 문서