본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 2장: 이벤트 스트리밍 아키텍처 기초
2026년 2월 12일·데이터·

2장: 이벤트 스트리밍 아키텍처 기초

이벤트 로그, 토픽과 파티션, 오프셋 관리, 이벤트 시간과 처리 시간의 차이, 워터마크, 윈도우 연산 등 스트림 처리의 핵심 개념을 체계적으로 학습합니다.

20분215자9개 섹션
streamingdata-engineering
공유
realtime-pipeline2 / 11
1234567891011
이전1장: 실시간 데이터 파이프라인의 필요성과 핵심 개념다음3장: Apache Kafka 심층 분석

학습 목표

  • 이벤트와 이벤트 로그의 개념을 정확히 이해합니다.
  • Topic(토픽), Partition(파티션), **Offset(오프셋)**의 관계를 파악합니다.
  • 이벤트 순서 보장의 범위와 한계를 학습합니다.
  • **Event Time(이벤트 시간)**과 **Processing Time(처리 시간)**의 차이를 이해합니다.
  • **Watermark(워터마크)**와 Window(윈도우) 연산의 원리를 학습합니다.

이벤트와 이벤트 로그

이벤트의 본질

1장에서 이벤트를 "특정 시점에 발생한 사실의 기록"이라고 정의했습니다. 여기서 핵심은 **불변성(immutability)**입니다. "사용자가 로그인했다"는 사실은 변경할 수 없습니다. 이벤트는 수정하거나 삭제하는 것이 아니라, 새로운 이벤트를 추가하는 방식으로 상태를 변경합니다.

이는 데이터베이스의 전통적인 CRUD 모델과 근본적으로 다릅니다. CRUD 모델에서는 레코드를 직접 수정(UPDATE)하거나 삭제(DELETE)합니다. 반면 이벤트 기반 모델에서는 모든 변경이 새로운 이벤트의 **추가(append)**로 기록됩니다.

이벤트 로그

**Event Log(이벤트 로그)**는 이벤트를 시간순으로 정렬한 추가 전용(append-only) 시퀀스입니다. 데이터베이스의 WAL(Write-Ahead Log)이나 Git의 커밋 히스토리와 동일한 개념입니다.

event-log-example
text
Offset 0: [2026-03-17T09:00:00Z] user.created  { userId: "U001", name: "Kim" }
Offset 1: [2026-03-17T09:00:05Z] order.placed  { orderId: "O001", userId: "U001" }
Offset 2: [2026-03-17T09:00:10Z] payment.completed { orderId: "O001", amount: 35000 }
Offset 3: [2026-03-17T09:00:15Z] order.shipped { orderId: "O001", trackingNo: "T001" }

이벤트 로그의 핵심 특성은 다음과 같습니다.

  • 추가 전용: 기존 이벤트를 수정하지 않고 항상 끝에 추가
  • 순서 보존: 이벤트가 기록된 순서가 유지됨
  • 재생 가능: 처음부터 다시 읽어 현재 상태를 복원 가능
  • 보존 기간 설정: 영구 보존 또는 일정 기간 후 삭제 설정 가능
Info

이벤트 로그는 단순한 메시지 큐와 다릅니다. 메시지 큐에서는 메시지가 소비되면 삭제되지만, 이벤트 로그에서는 소비 후에도 보존 기간 동안 유지됩니다. 따라서 여러 컨슈머가 같은 이벤트를 독립적으로, 각자의 속도로 읽을 수 있습니다.


토픽, 파티션, 오프셋

이벤트 스트리밍 시스템의 핵심 구성 단위를 살펴보겠습니다. 여기서는 Apache Kafka를 기준으로 설명하지만, 대부분의 스트리밍 플랫폼이 유사한 개념을 사용합니다.

Topic (토픽)

**Topic(토픽)**은 이벤트의 논리적 분류입니다. 관계형 데이터베이스의 테이블, 파일 시스템의 폴더에 비유할 수 있습니다. 예를 들어 orders, payments, user-events처럼 도메인별로 토픽을 구분합니다.

Partition (파티션)

하나의 토픽은 여러 **Partition(파티션)**으로 나뉩니다. 파티션은 토픽의 물리적 분할 단위이며, 각 파티션은 독립적인 이벤트 로그입니다.

파티션이 존재하는 이유는 병렬 처리입니다. 하나의 토픽에 초당 수만 건의 이벤트가 유입되더라도, 여러 파티션으로 분산하면 여러 컨슈머가 동시에 처리할 수 있습니다. 파티션 수는 토픽의 최대 병렬 처리 단위를 결정합니다.

이벤트가 어떤 파티션에 배치되는지는 **파티션 키(partition key)**에 의해 결정됩니다. 같은 키를 가진 이벤트는 항상 같은 파티션에 기록되므로, 해당 키에 대한 이벤트 순서가 보장됩니다.

ProducerExample.java
java
// 주문 ID를 파티션 키로 사용하면
// 같은 주문의 모든 이벤트가 동일 파티션에 기록됨
ProducerRecord<String, String> record = new ProducerRecord<>(
    "orders",           // 토픽
    order.getId(),      // 파티션 키
    orderEvent.toJson() // 값
);
producer.send(record);

Offset (오프셋)

**Offset(오프셋)**은 파티션 내에서 각 이벤트의 고유한 순차 번호입니다. 0부터 시작하여 이벤트가 추가될 때마다 1씩 증가합니다.

컨슈머는 자신이 마지막으로 읽은 오프셋을 기억하고 있어, 중단 후 재시작해도 이어서 읽을 수 있습니다. 이를 **오프셋 커밋(offset commit)**이라고 합니다.

offset-tracking
text
파티션 0: [0] [1] [2] [3] [4] [5] [6] [7] ...
                          ^
                   컨슈머 A의 현재 오프셋 = 3
                   (0, 1, 2까지 처리 완료)
Warning

오프셋은 파티션 단위로만 의미가 있습니다. 파티션 0의 오프셋 5와 파티션 1의 오프셋 5는 전혀 다른 이벤트입니다. 또한 파티션 간에는 순서 보장이 없으므로, 전역 순서가 필요한 경우 파티션을 1개로 설정해야 하지만 이는 병렬성을 포기하는 트레이드오프입니다.


이벤트 순서 보장

이벤트의 순서 보장은 스트림 처리에서 가장 자주 오해되는 개념 중 하나입니다.

파티션 내 순서 보장

동일 파티션 내에서는 이벤트 순서가 완벽하게 보장됩니다. 프로듀서가 이벤트 A를 먼저 보내고 이벤트 B를 보냈다면, 컨슈머도 반드시 A를 먼저, B를 나중에 읽습니다.

파티션 간 순서 미보장

서로 다른 파티션 사이에서는 순서가 보장되지 않습니다. 파티션 0에 먼저 기록된 이벤트가 파티션 1에 나중에 기록된 이벤트보다 늦게 처리될 수 있습니다.

실용적 설계 원칙

이 특성을 고려한 설계 원칙은 명확합니다.

  • 같은 엔티티의 이벤트는 같은 파티션에: 주문 ID, 사용자 ID 등 엔티티 식별자를 파티션 키로 사용합니다.
  • 파티션 간 순서가 필요하면 처리 엔진에서 해결: Flink의 윈도우나 워터마크를 활용합니다.
  • 전역 순서가 반드시 필요하면 파티션 1개: 처리량을 희생하지만 완전한 순서를 보장합니다.

이벤트 시간 vs 처리 시간

스트림 처리에서 "시간"은 단순하지 않습니다. 두 가지 핵심 시간 개념을 구분해야 합니다.

Event Time (이벤트 시간)

이벤트가 실제로 발생한 시간입니다. 모바일 앱에서 사용자가 버튼을 탭한 순간, IoT 센서가 측정값을 기록한 순간이 이벤트 시간입니다. 이벤트 페이로드에 타임스탬프로 포함됩니다.

Processing Time (처리 시간)

스트림 처리 엔진이 해당 이벤트를 실제로 처리하는 시간입니다. 네트워크 지연, 시스템 부하, 장애 복구 등으로 인해 이벤트 시간과 차이가 발생할 수 있습니다.

왜 구분이 중요한가

두 시간의 차이는 실질적 문제를 야기합니다.

time-skew-example
text
이벤트 시간    처리 시간       이벤트
09:00:00      09:00:02       주문 A 생성
09:00:05      09:00:06       주문 B 생성
09:00:03      09:00:10       주문 A 결제 (네트워크 지연으로 늦게 도착)

처리 시간 기준으로 "09:00~09:05 윈도우"를 집계하면, 주문 A의 결제 이벤트(이벤트 시간 09:00:03)가 빠집니다. 처리 시간 09:00:10에 도착했기 때문입니다. 반면 이벤트 시간 기준이라면 올바르게 포함됩니다.

Tip

대부분의 비즈니스 로직은 이벤트 시간 기준으로 처리해야 정확한 결과를 얻습니다. 처리 시간은 모니터링이나 시스템 성능 측정 용도로 적합합니다.


워터마크

**Watermark(워터마크)**는 "이 시점 이전의 모든 이벤트가 도착했다"는 시스템의 선언입니다. 늦게 도착하는 이벤트(late event)를 어디까지 기다릴 것인지를 결정하는 메커니즘입니다.

워터마크의 동작 원리

워터마크는 이벤트 시간의 하한선(lower bound)으로 동작합니다.

watermark-progression
text
시간 흐름 →
 
이벤트 도착:  [t=3] [t=1] [t=5] [t=4] [t=7] [t=6] [t=9]
워터마크:      W=0   W=0   W=1   W=1   W=4   W=4   W=6
               ↑               ↑                     ↑
            초기값         t=1까지 완료로 판단    t=6까지 완료로 판단

워터마크가 특정 시간 T를 넘으면, 시스템은 이벤트 시간이 T 이전인 모든 이벤트가 도착했다고 판단합니다. 이 시점에서 해당 시간 윈도우의 결과를 확정하고 출력할 수 있습니다.

워터마크 전략

워터마크를 얼마나 보수적으로 설정하느냐에 따라 지연 시간과 정확도 사이의 트레이드오프가 발생합니다.

  • 적극적 워터마크(짧은 지연 허용): 빠른 결과 출력, 늦은 이벤트 누락 가능
  • 보수적 워터마크(긴 지연 허용): 늦은 이벤트도 포함, 결과 출력 지연

Flink에서는 WatermarkStrategy를 통해 워터마크를 설정합니다.

WatermarkConfig.java
java
WatermarkStrategy
    .<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5))
    .withTimestampAssigner((event, timestamp) -> event.getTimestamp());

위 설정은 "이벤트가 최대 5초까지 늦게 도착할 수 있다"는 의미입니다. 워터마크는 관찰된 최대 이벤트 시간에서 5초를 뺀 값으로 설정됩니다.


윈도우 연산

무한히 흐르는 이벤트 스트림에서 집계 연산을 수행하려면 데이터를 유한한 단위로 나눠야 합니다. 이때 사용하는 것이 **Window(윈도우)**입니다.

Tumbling Window (텀블링 윈도우)

고정된 크기의 겹치지 않는 윈도우입니다. 가장 기본적인 윈도우 유형입니다.

tumbling-window
text
시간축: |----5분----|----5분----|----5분----|
윈도우:  [  W1     ] [  W2     ] [  W3     ]
이벤트:  * * *  *    *  * *      * * * * *

5분 텀블링 윈도우는 09:00~09:05, 09:05~09:10처럼 5분 단위로 정확히 분할되며, 각 이벤트는 정확히 하나의 윈도우에 속합니다.

Sliding Window (슬라이딩 윈도우)

윈도우 크기와 슬라이드 간격을 별도로 지정합니다. 윈도우가 겹칠 수 있어 하나의 이벤트가 여러 윈도우에 포함될 수 있습니다.

sliding-window
text
시간축:   |------10분------|
윈도우 1: [              ]
윈도우 2:      [              ]    (5분 간격으로 슬라이드)
윈도우 3:           [              ]

"지난 10분간의 평균값을 5분마다 갱신"과 같은 요구사항에 적합합니다.

Session Window (세션 윈도우)

이벤트의 활동 패턴에 따라 동적으로 윈도우가 결정됩니다. 일정 시간(gap) 이상 이벤트가 없으면 세션이 종료됩니다.

session-window
text
이벤트: * * *   *           * * *    *  *
갭:     < gap   < gap  > gap(세션종료)  < gap
세션:   [--- 세션 1 ---]     [--- 세션 2 ---]

사용자의 웹사이트 방문 세션을 분석할 때 유용합니다. 30분 동안 활동이 없으면 새 세션으로 간주하는 것이 대표적인 예입니다.

윈도우와 워터마크의 관계

윈도우의 결과는 워터마크에 의해 트리거됩니다. 워터마크가 윈도우의 끝 시간을 넘으면, 해당 윈도우의 모든 이벤트가 도착했다고 판단하고 결과를 출력합니다.

Warning

워터마크 이후에 도착하는 늦은 이벤트를 어떻게 처리할지도 중요한 설계 결정입니다. Flink에서는 allowedLateness로 추가 대기 시간을 설정하거나, **Side Output(사이드 아웃풋)**으로 별도 처리할 수 있습니다. 이에 대해서는 6장에서 자세히 다룹니다.


정리

이번 장에서는 이벤트 스트리밍의 핵심 기초 개념을 학습했습니다.

  • 이벤트 로그: 불변 이벤트의 추가 전용 시퀀스로, 스트리밍의 기본 데이터 구조입니다.
  • 토픽/파티션/오프셋: 이벤트의 논리적 분류, 물리적 분산, 순차 식별 체계입니다.
  • 순서 보장: 파티션 내에서만 보장되며, 파티션 키 설계가 핵심입니다.
  • 이벤트 시간 vs 처리 시간: 비즈니스 로직은 이벤트 시간 기준으로 처리해야 합니다.
  • 워터마크: 늦은 이벤트를 어디까지 기다릴지 결정하는 메커니즘입니다.
  • 윈도우: 무한 스트림을 유한 단위로 분할하여 집계하는 연산입니다.

다음 장 미리보기

3장에서는 이벤트 스트리밍의 사실상 표준인 Apache Kafka의 내부 아키텍처를 심층 분석합니다. KRaft 모드의 동작 원리, 브로커와 파티션의 레플리케이션, 프로듀서의 전송 보장 수준, 컨슈머 그룹의 리밸런싱 메커니즘까지 Kafka를 깊이 있게 이해합니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#streaming#data-engineering

관련 글

데이터

3장: Apache Kafka 심층 분석

Kafka의 핵심 아키텍처를 심층적으로 분석합니다. KRaft 모드, 브로커와 파티션 레플리케이션, 프로듀서 전송 보장, 컨슈머 그룹과 리밸런싱까지 Kafka의 내부를 이해합니다.

2026년 2월 14일·18분
데이터

1장: 실시간 데이터 파이프라인의 필요성과 핵심 개념

배치와 실시간 처리의 차이, 이벤트 드리븐 아키텍처, Lambda/Kappa 아키텍처, 핵심 구성요소를 살펴보며 실시간 데이터 파이프라인의 전체 그림을 이해합니다.

2026년 2월 10일·18분
데이터

4장: Kafka 프로듀서와 컨슈머 고급 패턴

Idempotent 프로듀서, 트랜잭셔널 프로듀서, Exactly-once 시맨틱스, 수동 오프셋 관리, 배치 최적화, Dead Letter Queue 등 프로덕션 수준의 Kafka 활용 패턴을 학습합니다.

2026년 2월 16일·18분
이전 글1장: 실시간 데이터 파이프라인의 필요성과 핵심 개념
다음 글3장: Apache Kafka 심층 분석

댓글

목차

약 20분 남음
  • 학습 목표
  • 이벤트와 이벤트 로그
    • 이벤트의 본질
    • 이벤트 로그
  • 토픽, 파티션, 오프셋
    • Topic (토픽)
    • Partition (파티션)
    • Offset (오프셋)
  • 이벤트 순서 보장
    • 파티션 내 순서 보장
    • 파티션 간 순서 미보장
    • 실용적 설계 원칙
  • 이벤트 시간 vs 처리 시간
    • Event Time (이벤트 시간)
    • Processing Time (처리 시간)
    • 왜 구분이 중요한가
  • 워터마크
    • 워터마크의 동작 원리
    • 워터마크 전략
  • 윈도우 연산
    • Tumbling Window (텀블링 윈도우)
    • Sliding Window (슬라이딩 윈도우)
    • Session Window (세션 윈도우)
    • 윈도우와 워터마크의 관계
  • 정리
  • 다음 장 미리보기