Kafka - KSQL MView

develkkm·2025년 11월 18일

0부터 시작하는 Kafka

목록 보기
16/18

Materialized View(MView)는 Kafka 기반 스트림 데이터에서 집계·가공된 결과를 빠르게 조회하기 위한 구조다.

일반 View와 달리 실제 저장 공간(State Store = RocksDB)을 가지며 기반 Stream/Table의 변경 사항을 반영해 최신 상태를 유지한다.

  • 대량 데이터 분석 SQL을 빠르게 조회하기 위해 사용됨
  • 원본 테이블 변경 시 즉시 또는 지연 적용
  • 내부적으로 RocksDB(State Store)를 사용하여 결과를 저장
  • MView를 조회하면 원본 데이터를 직접 처리하지 않아도 됨
  • CTAS/CSAS로 생성되는 MView는 Persistent Query 형태로 계속 실행됨

CTAS (Create Table As Select)

CTAS는 집계를 수행해 Table 형태의 MView를 만드는 방식이다.

Create Table customer_activity_mv01 
with (
  KAFKA_TOPIC = 'customer_activity_mv01_topic',
  KEY_FORMAT = 'KAFKA',
  VALUE_FORMAT = 'JSON',
  PARTITIONS = 3
)
As 
Select 
  customer_id, 
  avg(activity_point) as avg_point
from customer_activity_stream 
group by customer_id;
  • GROUP BY 기반으로 Key 단위 집계를 수행
  • 생성된 Table은 RocksDB에 상태(State)를 저장
  • 변경 사항은 changelog internal topic에 기록됨
  • MView는 이 changelog를 기반으로 최신 상태를 유지

CTAS + RocksDB

  1. 입력 Stream
    customer_activity_stream에서 레코드가 지속적으로 들어옴

  2. 집계 처리(Aggregation)
    customer_id 기준으로 avg(activity_point) 집계 수행

  3. State Store(RocksDB)에 저장
    각 customer_id의 최신 avg_point를 RocksDB에 저장

  4. Changelog Internal Topic 기록
    RocksDB 변경분을 changelog로 내부 토픽에 기록하여 복구 가능

  5. 결과 Topic(KAFKA_TOPIC)
    customer_activity_mv01_topic에 집계 결과가 출력됨


CSAS (Create Stream As Select)

CSAS는 MView를 Stream 형태로 생성하는 방식이다.

create stream customer_activity_strm_mv01 
with (
  KAFKA_TOPIC = 'customer_activity_strm_mv01_topic',
  KEY_FORMAT = 'KAFKA', 
  VALUE_FORMAT = 'JSON',
  PARTITIONS = 3
)
as
Select * 
from customer_activity_stream 
where activity_type in ('web_open', 'mobile_open');
  • 필터링 또는 변환된 “새로운 Stream”을 만드는 방식
  • RocksDB 상태 저장이 필요 없는 경우 사용
  • 단순 조건 필터링 기반 MView는 CSAS로 구성함

Group by

SELECT ACT_TYPE, COUNT(*) AS CNT, SUM(POINT) AS SUM_P,
       AVG(POINT) AS AVG_P, MAX(POINT) AS MAX_P
FROM CUSTOMER_ACTIVITY_STREAM 
GROUP BY ACT_TYPE 
EMIT CHANGES;
  • GROUP BY된 컬럼 기준으로 반드시 하나의 집합만 가진다.
  • SELECT 절에서는 GROUP BY 컬럼 또는 Aggregate 함수만 사용할 수 있다.
  • RocksDB를 기반으로 상태를 유지하며 집계 값을 지속적으로 업데이트한다.

Repartition

Repartition은 GROUP BY 기준 Key가 기존 Key와 다를 때 자동으로 발생한다.
하지만 Repartition에는 아래와 같은 단점과 비용이 존재한다.

Repartition의 단점

  1. 개별 Stream Task가 모든 파티션을 조회해야 하는 상황이 발생한다.
    → 파티션 단위로 분산 처리하지 못하므로 처리 효율이 떨어진다.

  2. 분산 병렬 처리가 제대로 수행되지 못한다.
    → 특정 Task가 특정 Key만 처리하는 구조가 깨지고 병렬성이 낮아진다.

  3. 데이터가 여러 노드에 분산된 경우
    네트워크로 데이터를 지속적으로 전송해야 한다.
    → 이로 인해 네트워크 대역폭 소모, 지연 증가, 시스템 부하 증가가 발생한다.

  4. RocksDB는 Local DB이기 때문에
    → 분산된 데이터를 기반으로 Stateful 연산을 수행할 수 없다.
    → 결국 Key가 동일 파티션으로 모여야만 RocksDB에서 상태를 유지할 수 있다.

Repartition 처리 흐름

위와 같은 단점이 있음에도 불구하고 GROUP BY를 수행하기 위해 Key를 맞추기 위해 Repartition이 실행된다.

  • ksqlDB는 자동으로 Repartition Topic을 생성한다.
  • 동일 Key가 동일 파티션으로 이동되도록 데이터를 재배치한다.
  • 이후 RocksDB에서 Key 기반 상태를 올바르게 유지한다.
profile
알던것을 더 확실하게

0개의 댓글