3459 words
17 minutes
[kafka]15. Streams
TL;DR (Too Long; Didn’t Read)
Key Takeaway
- 데이터 스트림은 기본적으로 무한히 늘어나는 데이터세트에 대한 추상화이다.
- 이벤트 스트림 모델은 기본적으로 순서가 있으며 재생이 가능하다.
- 카프카는 이벤트 스트림을 캡처하고 재생할 수 있다.
- 스트림 처리를 한다는 것은 단지 이벤트 스트림에서 연속적으로 데이터를 읽어와 뭔가 처리하고 결과를 내보내는 것을 의미한다.
- 카프카 스트림즈가 결과물을 카프카 토픽에 쓸 때 이벤트에 타임스탬프를 붙이는데 이때 적용되는 규칙이 있다.
- 시계열 데이터를 다룰 때는 timezone에 주의해야 한다.
- 테이블과 달리 스트림은 변경내역을 저장한다. 스트림은 기본적으로 변경을 유발하는 이벤트의 연속이다.
Overview
카프카 스트림즈를 사용하면 외부 처리 라이브러리에 의존하지 않고 어플리케이션 이벤트를 읽고 쓰는 기능을 구현할 수 있다. 데이터 아키텍처를 구축할 때 이벤트 스트림 관점에서 이를 다시 볼 수 있다.
1. 스트림 처리
이벤트스트림 모델의 속성
- 이벤트 스트림은 기본적으로 순서가 존재
- 데이터 레코드의 불변성 . 이벤트 스트림은 기본적으로 모든 트랜잭션을 포함한ㅁ
- 이벤트 스트림은 재생이 가능
몇가지 데이터 처리 패러다임
- 스트림 처리는 하나 이상의 이벤트 스트림을 계속해서 처리한다는 것을 의미
Request-Response
- 응답시간아 매우 짧은 경우(보통 몇 밀리세컨드 수준)
- 처리방식이 보통 블로킹 방식
- DB관점에서 보면 OLTP(OnLine Transaction Processing)에 해당.
Batch Processing
- 지연과 처리량이 모두 큰 경우
- 사전 설정된 시각에 실행
- 보통 DW 파이프라인 구축시 사용
Stream Processing
- 연속적 , 논블로킹
- dinamic pricing, fraud detection, real-time monitoring 등에 사용
2. 스트림 처리 개념
토폴로지
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '46px', 'fontFamily': 'arial', 'nodeSpacing': 100, 'rankSpacing': 80}}}%%
graph LR %% Source Processors S1[Source:<br/>orders-topic] --> P1 S2[Source:<br/>user-topic] --> P2
%% Stream Processors P1[Process:<br/>Filter Orders] --> P3 P2[Process:<br/>Enrich User Data] --> P3 P3[Process:<br/>Join Orders & Users] --> P4 P4[Process:<br/>Aggregate] --> P5 P5[Process:<br/>Transform] --> SINK
%% State Stores ST1[(State Store:<br/>Order Stats)] --- P4
%% Sink Processor SINK[Sink:<br/>enriched-orders-topic]
%% Styling classDef source fill:#afd,stroke:#333,stroke-width:3px,font-size:14px classDef processor fill:#ddf,stroke:#333,stroke-width:3px,font-size:14px classDef sink fill:#fdd,stroke:#333,stroke-width:3px,font-size:14px classDef store fill:#ffd,stroke:#333,stroke-width:3px,font-size:14px
class S1,S2 source class P1,P2,P3,P4,P5 processor class SINK sink class ST1 store
%% Layout linkStyle default stroke-width:2px- Source Processor : 토폴로지의 시작점. 카프카 토픽에서 데이터를 소비한다.
- Stream Processor : 데이터를 변환, 필터링, 집계하는 연산 단위.
- Sink Processor : 처리된 결과를 카프카 토픽으로 전송하는 종착점.
Time
스트림 처리 시스템에서 다루는 시간 개념들
Event Time
- 이벤트가 발생하여 레코드가 생성된 시점
log Append Time
- 이벤트가 카프카 브로커에 전달되어 저장된 시점
- 이벤트 시간의 근사치로 활용가능
Processing Time
- 스트림 처리 어플리케이션이 뭔가 연산을 수행하기 위해 이벤트를 받은 시점
State
- Kafka Streams 애플리케이션에서 State는 데이터 처리 과정 중에 유지되고 관리되는 중간 결과나 집계된 정보를 의미
- 스트림 처리 작업의 컨텍스트를 보존하고, 이전 데이터를 기반으로 현재 데이터를 처리할 수 있게 해주는 시스템
주요 용도
- 집계 연산(Aggregations): 시간 윈도우별 통계, 그룹별 집계 등을 계산할 때 중간 결과를 저장
- 조인 연산(Joins): 서로 다른 스트림이나 테이블의 데이터를 결합할 때 조인 대상 데이터를 보관
- 중복 제거(Deduplication): 이미 처리된 메시지를 식별하기 위한 정보를 저장
로컬 상태(내부 상태)
- 스트림처리 어플리케이션의 특정 인스턴스에서만 사용할 수 있는 상태
- 보통 인메모리 해시맵이나 RocksDB와 같은 로컬 디스크에 저장된 상태를 의미
외부상태
- 어플리케이션 데이터 저장소에서 유지되는 상태는 많은 경우
Stream Table Duality
- Stream Table Duality는 이벤트 시퀀스인 스트림과 상태정보의 스냅샷인 테이블이 서로 상호 변환 가능하며 동일한 데이터의 다른 표현 방식임을 의미
테이블 -> 스트림
- 테이블을 수정한 변경내역을 캡쳐
- 모든 트랜잭션 이벤트를 가져와서 스트림에 저장
- 일종의 CDC
스트림 -> 테이블
- 스트림에 포함된 모든 변경사항을 테이블에 적용. 이 작업을 Table Materialization이라고 함
- 메모리든 내부 상태 저장소든 테이블을 생성한 뒤 스트림에 포함된 이벤트를 처음부터 끝까지 모두 읽어서 상태를 변경.
Time Windows
- Time Window는 이벤트 스트림을 window라 불리는 일종의 구간 단위로 자른 것.
- 기본적으로 실시간 데이터 시스템에서는 무한한 데이터 스트림을 다루어야 하므로, 이를를 유한한 크기의 묶음으로 나누어 처리할 필요가 있음.
- 여기서 유한한 크기의 묶음을 Time Window라고 함.
Window Types
Session Window:
- 이벤트 발생 시점을 기준으로 동적으로 생성되는 윈도우
- 사용자의 웹사이트 방문 세션을 분석시 사용
- 특정 시간(타임아웃) 동안 새로운 이벤트가 발생하지 않으면 세션이 종료됩니다.
- 세션 윈도우의 크기는 고정되어 있지 않고, 이벤트 발생 패턴에 따라 동적으로 결정됨
Hopping Window:
- 일정한 간격으로 이동하면서 겹치는 기간을 포함할 수 있는 윈도우.
- 윈도우의 크기와 이동 간격(advance interval)을 별도로 설정할 수 있음.
- 다ㅏ10분 크기의 윈도우를 5분마다 이동시키면, 연속된 두 윈도우는 5분의 겹치는 구간이 생김
Advance Interval:
- Hopping Window에서 윈도우가 이동하는 간격
- 이 값이 윈도우 크기보다 작으면 윈도우들이 겹치게 되고, 같으면 텀블링 윈도우가 됨
- Advance interval < Window size = > Hopping Window (Overlap)
- Advance interval = Window size = > Tumbling Window (Non-overlap)
- 1시간 윈도우를 30분마다 이동시키면 30분의 advance interval을 가진 1시간 크기의 Hopping Window가 생성
Tumbling Window (텀블링 윈도우):
- 겹치지 않는 고정 크기의 윈도우
- 윈도우의 크기와 advance interval이 동일한 특별한 형태의 Hopping Window
- 매 시간 정각에 시작하는 1시간 단위의 윈도우들은 서로 겹치지 않고 연속적으로 이어집니다.
Grace Period (유예 기간):
- 윈도우의 종료 시점 이후에도 늦게 도착하는 데이터(지연 데이터)를 처리하기 위한 추가 시간
- 실제 환경에서는 네트워크 지연이나 시스템 문제로 인해 데이터가 순차적으로 처리되지 않을 수 있음
- Grace period를 설정하면 윈도우 종료 후에도 일정 시간 동안은 해당 윈도우에 속하는 늦은 데이터를 처리 가능
처리 보장하기
- 스트림 처리 어플리케이션에 있어서 핵심적인 요구조건은 장애가 발생했을 경우에도 각각의 레코드를 한 번만 처리할 수 있는 능력
processing.guarantee옵션으로 설정 가능
3. 스트림 디자인 패턴
단일 이벤트 처리
- 핵심은 각각의 이벤트를 독립적으로 처리하는것
- 스트림의 이벤트를 읽어와 각각의 이벤트를 처리하고 쓰는 것.
Local State을 사용한 스트림 처리
State를 사용하는 순간 고려해야 할 사항
- local state를 사용한 local 집계
- kafka partitioner를 사용해 동일한 키에 대한 모든 이벤트가 동일한 파티션에 쓰이도록 함
- 각각의 application instance는 동일한 파티션을 처리하게 되어있음
메모리 사용
영속성
리밸런싱
다단계 처리/리파티셔닝
1. key 별 변경사항 추적
2. 리파티셔닝
- reduce 단계별로 application instance 가 필요
- 스트리밍 어플리케이션은 map reduce와 유사하지만 어플리케이션 레벨에서 단계를 처리 가능
스트림-테이블 조인
이벤트 소싱 방식 Materialized View
- DB와 같은 외부 저장소를 포함하는 토폴로지에서 시작
- 성능과 가용성을 확보하려면 스트리밍 어플리케이션 안에 DB에 저장된 데이터를 캐시해야 함
- 캐시정보를 만료되지 않게 유지해야 함
- DB에 가해지는 모든 변경점을 이벤트 스트림에 담음으로써 이를 해결
- CDC(Change Data Capture)를 사용해 스트림중 하나가 로컬에 캐시된 테이블에 대한 변경사항을 나타냄
- 스트림-테이블 조인이라 함
테이블-테이블 조인
- equal join
- 기본적으로 윈도우 처리되지 않는 연산
- kafka streams에서는 두 테이블에 대해 외래 키 조인 지원
스트리밍 조인
- Window Join 이라고 함
- 두 개의 스트림을 조인할 경우 한쪽 스트림에 포함된 이벤트를 같은 키값과 함께 같은 시간 윈도우에 발생한 다른 쪽 스트리밍 이벤트와 맞춰야 한다. 따라서 과거와 현재 이벤트 전체를 조인하게 한다. 이때문에 Stream 조인을 Window Join이라고 함.
Out-of-sequence 이벤트 처리
- 잘못된 시간에 스트림에 도착한 이벤트를 처리하는 것
- 순서를 복구하기 위해 이벤트를 묶을 수 있어햐 함
- 결과를 변경할 수 있어야함
- kafka streams는 항상 집계 결과를 결과 토픽에 씀
재처리
Interactive Query
- 처리결과가 테이블 형태인 경우 상태저장소 자체에서 바로 결과를 읽어 오는것
4. 스트림 처리 구현
5. 카프카 스트림즈 아키텍처
토폴로지 생성
토폴로지 최적화
kafka streams는 어플리케이션 실행단계
- KStreams, KTable 객체 생성 후 여기에 DSL을 적용 -> 논리적 토폴로지 정의
- Stream Builder를 통해 논리적 토폴로지를 물리적 토폴로지로 변환
- KafkaStreams.bulder()를 통해 물리적 토폴로지를 실행
2번째 단계에서 최적화가 이루어짐
StreamsConfig에서 optimization 옵션을 통해 최적화 수준을 설정할 수 있음
토폴로지 테스트
토폴로지 스케일링
장애 처리
- Task 고가용성 지원을 위한 Consumer Cordinator 사용
6. 스트림 처리 활용사례
- 실시간으로 변경사항을 전달받아서 처리하는 케이스
7. 스트림 처리 프레임워크 선택을 위한 고려사항
기본적으로 어떠한 형태의 어플리케이션을 개발하려는지 고려해야 한다.
고려할 요구사항
- 데이터 수집
- 밀리초 단위 작업
- 비동기 마이크로 서비스
- 준 실시간 단위 분석
Concepts
Concept
- Message bus : 메시지 전송을 위한 일종의 Infrastructure를 제공하는 것.
- 이벤트 스트림 : 메시지 전송을 위한 일종의 Infrastructure를 제공하는 것.
- Topology : 토폴로지. 카프카 스트림즈 애플리케이션의 데이터 처리 로직을 표현한 일종의 DAG. 모든 이벤트가 입력에서 출력으로 이동하는 동한 수행되는 작업과 변환 처리의 집합. Source, Processor, Sink로 구성.
- Source Stream :토폴로지의 시자점. 카프카 토픽에서 데이터를 소비하는 시작점.
- Stream Processor : 데이터를 변환, 필터링, 집계하는 연산 단위. 처리 영역
- Sink Stream : 처리된 결과를 카프카 토픽으로 전송하는 종착점.
- Event Time : 이벤트가 발생하여 레코드가 생성된 시점
- log Append Time : 이벤트가 카프카 브로커에 전달되어 저장된 시점
- Processing Time : 스트림 처리 어플리케이션이 뭔가 연산을 수행하기 위해 이벤트를 받은 시점
- State : Kafka Streams 애플리케이션에서 State는 데이터 처리 과정 중에 유지되고 관리되는 중간 결과나 집계된 정보를 의미. 스트림처리의 컨텍스트를 보존하고 이전 데이터를 기반으로 현재 데이터를 처리할 수 있게 해주는 시스템.
- State Store : 상태 정보를 저장하는 물리적 저장소. RocksDB와 같은 내장 데이터베이스나 인메모리 해시맵 형태로 구현됨
- Changelog Topic : State Store의 변경사항을 기록하는 Kafka 토픽입니다. 이를 통해 장애 발생 시 상태를 복구할 수 있음.
- Stream Table Duality : 이벤트 시퀀스인 스트림과 상태정보의 스냅샷인 테이블이 서로 상호 변환 가능하며 동일한 데이터의 다른 표현 방식임을 의미
stateful : 기존 상태에 의존 하는것 statefless : 기존 상태에 의존 하지 않는것
References
- 카프카 핵심가이드
[kafka]15. Streams
https://yjinheon.netlify.app/posts/02de/kafka/de-kafka-15_kafka_streams/