5 분 소요

DW에서 fact를 꼭 이벤트 단위로만 만들어야 하는 것은 아닙니다. 어떤 문제는 이벤트보다 상태 를 저장하는 편이 훨씬 낫습니다.

특히 아래 같은 지표를 자주 본다면 더 그렇습니다.

  • 최근 7일 활성 유저
  • 30일 이상 쉬었다가 돌아온 유저
  • 연속 14일 활동 유저

이런 지표를 매번 원천 로그에서 다시 계산하면, 필요할 때마다 로그를 처음부터 다시 뒤져야 합니다. 한두 번은 괜찮지만, 이게 반복되면 분석보다 로그 읽는 데 돈과 시간이 더 들어갑니다.

그래서 이런 경우에는 상태 스냅샷(State Snapshot) 모델링이 꽤 잘 맞습니다.

먼저 스냅샷 테이블이 어떻게 생겼는지부터 봐야 합니다

상태 스냅샷 테이블은 보통 이런 느낌입니다.

day_dt user_id service_code is_active_today first_active_day_dt last_active_day_dt inactive_days_before_today active_streak_days
2025-03-07 1001 app true 2025-02-10 2025-03-07 0 5
2025-03-07 1002 app false 2025-01-05 2025-03-03 3 0
2025-03-07 1003 app true 2025-03-07 2025-03-07 12 1

이 테이블이 말해주는 것은 단순합니다.

  • 1001 은 오늘 활동했고, 5일 연속 활동 중입니다
  • 1002 는 오늘은 활동하지 않았고, 마지막 활동은 3일 전입니다
  • 1003 는 오늘 돌아왔고, 오늘이 최초 활동일입니다

즉 원천 이벤트를 매번 다시 읽지 않아도, 오늘 시점에서 이 사용자가 어떤 상태인지 를 바로 알 수 있습니다.

상태 스냅샷 모델링은 결국 이 테이블을 매일 한 장씩 쌓아가는 방식입니다.

상태 스냅샷이란 무엇인가

아이디어는 단순합니다.

매일 사용자 상태를 한 장의 테이블로 고정해두고, 이후 지표 계산은 이 스냅샷을 기준으로 합니다.

계산 방식도 어렵지 않습니다.

오늘 스냅샷 = 어제 스냅샷 + 오늘 활동 여부

구성도를 보면 아래와 같습니다.

graph LR
    A["전일 사용자 상태"] --> C["오늘 상태 계산"]
    B["당일 활동 로그"] --> C
    C --> D["당일 상태 스냅샷"]

즉 이벤트를 처음부터 끝까지 다시 읽는 대신, 어제까지 누적된 상태에 오늘 활동만 반영하는 방식입니다.

왜 이 방식이 편한가

가장 큰 이유는 조회가 단순해진다는 점입니다.

예를 들어 AU_30 같은 지표를 로그 기반으로 계산하려면 최근 30일 동안의 로그를 다시 읽어야 합니다. 초기에는 이 방식도 괜찮지만, 데이터가 커지고 조회가 반복되기 시작하면 비용과 실행 시간이 빠르게 늘어납니다.

반면 상태 스냅샷 테이블이 있으면, 매일 사용자 상태를 미리 정리해 두기 때문에 오늘 기준 스냅샷 파티션만 읽어도 대부분의 활성 사용자 지표를 계산할 수 있습니다.

즉, 이벤트를 처음부터 다시 해석하는 대신, 이미 정리된 사용자 상태를 조회하는 방식에 가깝습니다.

예를 들면 아래처럼 볼 수 있습니다.

  • DAU (Daily Active Users) : 오늘 활동한 사용자 수입니다.
    • is_active_today = true
  • NDAU (New Daily Active Users) : 신규 활성 사용자입니다.
    • is_active_today = true and first_active_day_dt = day_dt
  • AU_N (Active Users in N days) : 최근 N일 안에 한 번이라도 활동한 사용자 수입니다.
    • DATE_DIFF(day_dt, last_active_day_dt, DAY) < N
  • RES_N (Resurrected Users after N inactive days) : N일 이상 쉬었다가 오늘 다시 돌아온 사용자 수입니다.
    • is_active_today = true and inactive_days_before_today >= N

이렇게 바뀌면 쿼리는 더 이상 긴 기간의 이벤트 로그를 반복해서 읽는 작업이 아니라, 사용자 상태를 조회하는 작업에 가까워집니다.

예전에는 지표 하나 볼 때마다 로그를 한참 뒤져야 했다면, 스냅샷 모델링에서는 이미 정리된 상태표를 펼쳐보는 느낌에 가깝습니다.

장점은 꽤 분명합니다

1. 가변 N 지표에 강합니다

7일, 30일, 90일처럼 N이 자주 바뀌어도 최신 스냅샷만 읽으면 대응하기 쉽습니다.

2. 로그 재스캔 비용을 줄입니다

이게 가장 큽니다. 긴 기간 로그를 반복해서 읽지 않아도 됩니다.

3. 설명이 쉽습니다

전일 상태 + 당일 활동 이라는 구조가 직관적입니다. 왜 이런 지표가 이렇게 계산됐는지 설명하기도 좋고, 장애가 나도 어디서 어긋났는지 추적하기가 상대적으로 쉽습니다.

4. 재처리 전략을 세우기 좋습니다

최근 3일 정도를 다시 계산하는 식으로 운영하면 지연 수집이나 부분 장애 대응이 쉬워집니다. 파티션 단위 DELETE + INSERT 도 잘 맞습니다.

5. 품질 검증 포인트가 분명합니다

예를 들면 이런 검증을 걸기 좋습니다.

  • NDAU <= DAU
  • first_active_day_dt <= last_active_day_dt
  • 활동하지 않았는데 streak가 증가하면 안 됨

이런 규칙이 명확하면 DQ Gate도 만들기 쉽습니다.

단점도 있습니다

좋은 점만 있는 것은 아닙니다.

1. 적재 로직은 오히려 복잡해집니다

조회는 쉬워지지만, 스냅샷을 만드는 쪽은 더 어렵습니다.

  • 신규 유저
  • 복귀 유저
  • 하루 쉬고 다시 온 유저
  • 늦게 들어온 로그

이런 케이스를 모두 다뤄야 하기 때문입니다.

2. 지연 데이터 정책이 중요합니다

어제 스냅샷을 만들었는데 어제 로그가 오늘 늦게 들어오면 상태가 틀어질 수 있습니다. 그래서 최근 며칠 재처리 같은 운영 전략이 필요합니다.

3. 테이블이 커질 수 있습니다

유저 수가 많고 매일 상태를 쌓으면 저장 비용도 무시하기 어렵습니다. 그래서 파티셔닝, 클러스터링, 휴면 유저 관리 기준이 중요합니다.

4. 활동 기준이 바뀌면 상태 정의도 같이 흔들립니다

상태 스냅샷은 생각보다 원천 정의에 강하게 의존합니다.

예를 들어 아래 같은 변경이 생기면 다시 점검해야 합니다.

  • 무엇을 활동으로 볼 것인지 바뀌는 경우
  • 서비스 기준 타임존이 바뀌는 경우
  • 특정 이벤트를 제외하거나 추가하는 경우

is_active_today 기준이 흔들리면 그 위에 있는 DAU, NDAU, RES_N, streak 도 같이 흔들립니다. 그래서 스냅샷 테이블은 편하지만, 한번 정의했다고 끝나는 테이블은 아닙니다.

실제 운영하면서 조심해야 할 포인트

모델은 예뻐도 운영에서 삐끗하면 바로 티가 납니다. 상태 스냅샷 fact는 특히 아래를 조심하는 편이 좋습니다.

1. 재처리 범위를 너무 짧게 잡지 않는 것이 좋습니다

최근 1일만 재처리하도록 잡아두면, 늦게 들어온 로그를 충분히 흡수하지 못할 수 있습니다. 반대로 너무 길게 잡으면 비용이 다시 커집니다.

즉 재처리 윈도우는 감이 아니라 실제 지연 분포 를 보고 정하는 편이 좋습니다.

2. 휴면 유저를 어디까지 스냅샷에 남길지 정해야 합니다

모든 유저 상태를 매일 끝까지 쌓을지, 일정 기간 이상 비활성 유저는 제외할지 기준이 필요합니다.

이 기준이 없으면 테이블 크기가 빨리 커지고, 반대로 너무 일찍 제외하면 복귀 유저 계산이 애매해질 수 있습니다.

3. 상태 컬럼끼리 서로 모순되지 않는지 계속 검사해야 합니다

예를 들면 아래는 운영 중에 자주 확인할 만한 항목입니다.

  • last_active_day_dt < first_active_day_dt
  • is_active_today = false 인데 active_streak_days > 0
  • inactive_days_before_today > 0 인데 동시에 오늘 활동한 처리와 모순되는 경우

이런 검증은 한 번 넣고 끝내지 말고, 배치마다 자동으로 확인하는 편이 좋습니다.

4. 스냅샷만 믿고 원천 로그를 너무 멀리 보내면 안 됩니다

상태 스냅샷은 조회용으로는 강하지만, 모든 질문에 답해주지는 않습니다. 특정 이상 케이스를 디버깅하거나 활동 정의를 다시 검증하려면 결국 원천 로그가 필요합니다.

즉 스냅샷은 원천 로그를 대체하는 것이 아니라, 원천 로그를 매일 다시 읽지 않기 위해 앞단에 두는 운영용 모델 에 더 가깝습니다.

언제 특히 잘 맞는가

상태 스냅샷 fact는 아래 상황에서 특히 잘 맞습니다.

  • 활성 유저 지표가 중요할 때
  • 복귀, 이탈, 연속 활동 같은 상태 기반 지표를 자주 볼 때
  • 로그 규모가 커서 기간 재스캔이 부담될 때
  • 배치 운영에서 안정성과 복구 가능성이 중요할 때

반대로 세부 이벤트 흐름을 계속 깊게 분석해야 하는 문제라면 이것만으로는 부족합니다. 그건 원천 이벤트나 세션 레이어를 같이 봐야 합니다.

정리

상태 스냅샷 모델링은 결국 비싼 계산을 미리 상태로 바꿔두는 전략입니다.

조회 시점에는 단순하고 빠르고, 운영 시점에는 재처리와 멱등성이 중요합니다. 대용량 활성 사용자 지표를 자주 계산해야 한다면, 이벤트를 매번 다시 읽는 것보다 상태를 매일 쌓아두는 쪽이 훨씬 실용적일 때가 많습니다.

댓글 남기기

스팸 방지를 위해 짧은 시간에 반복 등록은 제한됩니다.

댓글 목록

관리자 보기