[실시간] 체크포인트, offset, 로깅(logging)과 장애발생 시 복구 방법

2025. 7. 14. 14:35·데이터 엔지니어

 

데이터 수집 파이프라인에서

실시간으로 데이터를 처리하는 스트리밍 패턴에서

장애 발생시 어떻게 데이터를 처리할까? 어떻게 처리해야 정합성을 유지할까?

이때 두가지 방식이 혼합해서 사용한다.

체크포인트, 로깅

 

(1) 체크포인트와 로깅

  • 체크포인트
    • 무엇을 저장하나? 특정시점의 전체 상태를 저장(Snapshot) + 그 체크포인트까지 처리된 이벤트 인덱스값(offset) 
    • 활용
      • 장애 발생 시  가장 최근의 체크포인트로 복구 + 로깅의 이벤트 기록을 순차적으로 재처리함
  • 로깅
    • 시간순으로 발행된 이벤트를 순차적으로 그대로 저장하는 것
    • 활용
      • 장애 발생 시 이벤트 기록들을 replay해서 데이터를 복구
여기까지만 봐도 뭔말인지 모를 용어들이 난무한다.
체크포인트, 로깅뭔지 알려면 좀더 구체적인 예시로 이해하는게 좋다.

그전에 이벤트, 상태라는게 뭔지 알고 가야한다.

그다음 오프셋, 스냅샷이 의미하는바가 뭔지, 왜 체크포인트를 유지하는게 어려운지, 
로깅이 그냥 로그를 저장하는 정도로 알았지만 replay가 도대체 뭔지는 실제 예시를 보면 한번에 이해된다.

 

 

(2) 예시로 이해하기

<사전지식>

이벤트 vs 상태

  • 이벤트: "무슨 일이 일어났다"는 사실 (불변) - 시스템으로 들어오는 입력데이터
  • 상태: 이벤트들을 처리한 현재 결과값 (변함)

실무 예시:

이벤트: "유저A가 기생충에 좋아요를 눌렀다"
상태: 유저A의 liked_movies = ["기생충", "올드보이", "타짜"]

 

이벤트는 고객행동으로 인해 프로듀서가 발행한 로그 데이터 이고

상태는 이벤트를 기반으로 처리해서 사용자의 좋아요누른 영화 리스트를 업데이트 한 결과값을 의미한다.

이걸 반드시 집고 넘어가야 체크포인트, 로깅을 활용하는 걸 정확히 이해가능하다.

 

체크포인트, 로깅 예시로 알아보자

실무 상황: 실시간 추천 시스템

우리가 Netflix 같은 스트리밍 서비스에서 실시간 추천 시스템을 운영한다고 해보자.

사용자 행동 데이터가 계속 들어옴:

15:30:01 - 유저A가 "기생충" 시청 시작
15:30:15 - 유저A가 "기생충" 30초 시청 후 skip
15:30:20 - 유저B가 "오징어게임" 좋아요 클릭
15:30:25 - 유저A가 "범죄도시" 시청 시작

로깅 방식:
이벤트를 순서대로 계속 쌓아놔:
Event1: {user: A, action: "start_watch", movie: "기생충", time: 15:30:01}
Event2: {user: A, action: "skip", movie: "기생충", time: 15:30:15}
Event3: {user: B, action: "like", movie: "오징어게임", time: 15:30:20}
Event4: {user: A, action: "start_watch", movie: "범죄도시", time: 15:30:25}

체크포인트(스냅샷) 방식:

15:30:20 시점의 전체 사용자 상태를 통째로 저장:
{
    userA: {preference: ["액션", "스릴러"],     recently_watched: ["기생충"], skip_count: 1},
    userB: {preference: ["드라마", "스릴러"], liked_movies: ["오징어게임"]},
    userC: {preference: ["코미디"],                watching_now: "극한직업"}
    ... (전체 사용자 데이터)
}

핵심 차이점:
1. 저장하는 내용이 다름
로깅: "무슨 일이 일어났는지" 이벤트 기록
체크포인트: "현재 상태가 어떤지" 전체 스냅샷

 

 

그럼 이제 복구를 이걸 이용해서 어떻게 할까?

각 방식으로만 복구를 한다고 생각해보자
로깅:
전체 이벤트를 처음부터 다시 쭈욱 처리해서 상태값을 업데이트 해야한다.
(이벤트양이 많으면 처리할게 너무 많아진다)

체크포인트:
장애발생과 체크포인트의 시점이 일치하지 않는게 일반적이다.
그 사이의 기간동안의 유실된 이벤트로 인해 상태값이 정확하지 않게 된다.

결론 및 개선된 복구전략:
두가지 방식을 혼용해서 사용함.
장애 발생 시 가장 최근 체크포인트로 복구하고 
그때를 기준으로 처리된 이벤트 오프셋(offset)값을 활용해서
로깅에서 저장된 이벤트를 처리해서 상태값을 업데이트 한다.(replay) 



예시상황에 적용해보자,

15:30:01 - 유저A가 "기생충" 시청 시작
15:30:15 - 유저A가 "기생충" 30초 시청 후 skip
15:30:20 - 유저B가 "오징어게임" 좋아요 클릭
15:30:25 - 유저A가 "범죄도시" 시청 시작

로깅 방식:
이벤트를 순서대로 계속 쌓아놔:
Event1: {user: A, action: "start_watch", movie: "기생충", time: 15:30:01}
Event2: {user: A, action: "skip", movie: "기생충", time: 15:30:15}
Event3: {user: B, action: "like", movie: "오징어게임", time: 15:30:20}
Event4: {user: A, action: "start_watch", movie: "범죄도시", time: 15:30:25}

체크포인트(스냅샷) 방식:

15:30:20 시점의 전체 사용자 상태를 통째로 저장:
{
    userA: {preference: ["액션", "스릴러"],     recently_watched: ["기생충"], skip_count: 1},
    userB: {preference: ["드라마", "스릴러"], liked_movies: ["오징어게임"]},
    userC: {preference: ["코미디"],                watching_now: "극한직업"}
    ... (전체 사용자 데이터)
}


시스템이 15:30:30에 장애가 났다고 가정해보자:

1. 체크포인트 생성시 Offset를 저장 (Kafka 예시)

처리 상태를 따로 기록:
Topic: user-events Partition 0: [event1, event2, event3, event4, event5]
                                                                    ↑ offset=2 (여기까지 처리완료)

엔지니어의 독백:
"아, 시스템이 죽었네. 어디까지 처리했는지 확인해보자...
Consumer group의 offset을 보니까 offset=2까지 처리했구나.
그럼 offset=3부터 다시 처리하면 되겠다."

2. 실제 복구 과정:
1. 시스템 재시작 - 가장 최근 체크포인트 스냅샷으로 복구
2. 마지막 처리된 offset 확인 (offset=2)
3. offset=3부터 이벤트 재처리 시작
4. event3, event4, event5... 순차 처리


 

 

 

'데이터 엔지니어' 카테고리의 다른 글

[Delivery guarantee] at most once, at least once, exactly once  (0) 2025.07.18
[실시간] RBML, SBML HML  (3) 2025.07.14
'데이터 엔지니어' 카테고리의 다른 글
  • [Delivery guarantee] at most once, at least once, exactly once
  • [실시간] RBML, SBML HML
버터젤리
버터젤리
  • 버터젤리
    across the universe
    버터젤리
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • 데이터 엔지니어 (3)
        • MLOPs (0)
      • 인프라 및 클라우드 (0)
        • Docker (0)
        • Kubernetes (0)
      • Development(개발) (5)
        • 백엔드 (0)
        • 개발 Core (5)
      • LLM (4)
        • 강화학습 (0)
        • LLM (4)
        • Generator (0)
      • PM (7)
        • IT Trends (0)
        • 세미나 후기 (7)
      • Deep learning (30)
        • 기초이론 (8)
        • 컴퓨터비전 (6)
        • 자연어처리 (5)
        • Anomaly Detection (6)
      • Machine learning (25)
      • Computer Science (26)
        • Linux (21)
        • 네트워크 (1)
        • 하드웨어 (4)
        • 운영체제(OS) (0)
      • 프로그래밍 언어 (17)
        • Python (8)
        • Pytorch (8)
        • Tensorflow (0)
      • Tools (16)
        • 주피터노트북 (7)
        • 깃(Git) (3)
        • 파이참 (5)
      • Book (2)
      • LIFE (0)
      • 창고 (0)
        • AI 인턴 (0)
      • 회고 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    객사오
    nohup
    BatchNormalization
    백그라운드
    batch normalization
    @
    #git#github
    역할
    jupyer notebook
    hml
    BN
    리눅스#파일이동#특정이름#포함
    sbml
    객체지향의사실과오해
    객체지향
    데코레이터
    책임
    역할과책임
    rbml
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
버터젤리
[실시간] 체크포인트, offset, 로깅(logging)과 장애발생 시 복구 방법
상단으로

티스토리툴바