Lakehouse, Trinio insert 대안

Jeonghak Cho·2025년 9월 15일

Bigdata

목록 보기
29/30

데이터레이크에서 Flink가 필요한 이유

데이터레이크 환경(특히 Iceberg/Hudi/Delta 같은 테이블 포맷 기반 레이크하우스)에서 Flink가 사실상 반드시 들어와야 하는 이유는 “실시간 처리”라는 성격 때문이다.

실시간 Ingestion

Flink가 Kafka → Iceberg를 이어주는 실시간 ingestion 엔진 역할을 함.

  • 데이터레이크는 저장소 그 자체일 뿐, Kafka → Iceberg로 직접 데이터를 넣어주지 않음.
  • Kafka Connect 같은 것도 있지만 단순 append만 가능, CDC/업데이트/정렬 같은 고급 기능은 부족.
  • Flink는 Kafka Connector + Iceberg Connector를 지원 → 실시간으로 레이크에 테이블 형태로 저장 가능.

CDC(Change Data Capture) 처리

운영 DB의 트랜잭션 → 데이터레이크 테이블 동기화가 가능해짐.

  • 데이터레이크는 Append-only 로그가 아니라 테이블 형태 (Insert/Update/Delete) 를 지원해야 함.
  • Kafka Consumer는 Insert만 쉽게 할 수 있고, Update/Delete 처리는 직접 로직을 구현해야 함.
  • Flink는 Debezium CDC + Flink SQL로 업데이트/머지 이벤트를 Iceberg/Hudi에 자동 반영.

Exactly-once 보장

데이터 품질을 보장하려면 Flink가 중간에서 조정자 역할.

  • 데이터레이크의 핵심 가치는 정확한 데이터 품질.
  • Kafka → Flink → Iceberg 파이프라인에서 Flink가 체크포인트/세이브포인트로 Exactly-once 보장.
  • 단순 Kafka Consumer → S3 적재는 중복/유실 가능성이 높음.

이벤트 시간 기반 처리

실시간 로그 스트림을 “분석 가능한 시계열 테이블”로 변환.

  • 데이터레이크는 보통 배치 성격인데, 실시간 데이터는 지연/순서 꼬임이 흔함.
  • Flink는 Event Time / Watermark 로 늦게 들어온 데이터도 올바른 시점에 정렬 가능.
  • 이렇게 적재된 Iceberg 테이블은 시간순 정확한 분석에 사용 가능.

Lakehouse/ELT 엔진과의 연결

Spark만으로는 ingestion 실시간성이 약하고, Kafka만으로는 테이블화가 불가. Flink가 꼭 필요.

  • Spark/Trino/Presto는 보통 읽기 전용(쿼리/배치) 으로 데이터레이크를 사용.
  • Flink는 쓰기 엔진(ingestion/stream processing) 으로 동작.
  • 이 조합으로 읽기(Spark/Trino) + 쓰기(Flink) 가 완성 → 레이크하우스 운영 가능.

Spark의 실시간성 한계

단순 배치 적재 (예: 하루 1번, 10분 단위 로그 적재)는 Spark INSERT 충분하나 실시간 적재/분석 (예: Kafka 이벤트를 대시보드 1초 내 반영) 을 위해서는 Spark INSERT는 한계가 있기 때문에 Flink가 필요하다. 일반적으로 Spark는 Batch ETL / 대규모 처리용, Flink는 실시간 Ingestion/CDC용 으로 역할을 분리한다.

Spark INSERT 동작 특성

Spark는 Micro-batch/Batch 엔진 → 기본적으로 “한번에 많은 데이터를 처리”하는 데 최적화.

INSERT 시 동작 흐름:

  • Driver에서 Job 생성
  • Executor에서 읽고 변환
  • 결과를 Parquet 파일 단위로 저장
  • Iceberg snapshot/manifest 갱신

Spark INSERT는 배치 단위 commit → commit 완료 시점에만 테이블이 갱신됨.

  • Flink는 Streaming-first 엔진 → 레코드 단위(혹은 소량의 미니 배치)로 바로 Iceberg Sink에 push.
  • Checkpoint 단위로 Exactly-once 보장하며, 지연(latency)이 ms~초 단위.
  • Kafka 메시지가 들어오면 거의 바로 Iceberg에 반영됨.

Spark INSERT의 한계 (실시간성 관점)

Latency

  • Spark는 job 실행 + shuffle + 파일 commit 과정 때문에 수 초~수 분 단위 지연 발생.
  • Flink는 수 ms~초 단위로 반영 가능.

Continuous ingest 부적합

  • Spark Structured Streaming도 있긴 하지만, micro-batch 방식이라 near real-time 수준.
  • Flink의 continuous streaming과 비교하면 밀리초 단위에서는 따라가기 어려움.

Update/Delete/CDC 반영 어려움

  • Spark Insert는 append 중심 → CDC 처리 시 복잡한 MERGE INTO job 필요.
  • Flink는 CDC 이벤트를 바로 upsert 처리 가능.

Flink를 무조건 사용해야 하나

데이터 파이프라인의 성격에 따라 선택지가 달라진다. Flink는 무조건 써야 하는 건 아니지만, 실시간 데이터 레이크(Iceberg/Hudi/Delta) 구축이라면 → Flink가 사실상 표준 선택지가 된다.

Flink를 반드시 써야 하는 경우

실시간 집계 / 분석

  • 예: 최근 5분간 주문 수 / 사용자별 세션 집계 / 이벤트 시간 기반 윈도우
  • 단순 소비로는 구현이 어렵고 Flink 같은 스트리밍 엔진 필요

Exactly-once 보장 필요

  • 금융/결제/로그 분석처럼 중복/유실 없는 데이터가 필수일 때
  • Kafka Consumer만으로는 구현이 매우 까다롭지만 Flink는 내장

다양한 Sink 연동

  • Kafka → Iceberg / Hudi / Delta / Elastic / JDBC 같은 데이터 레이크·DB 저장
  • Flink는 커넥터로 쉽게 처리

CDC(Change Data Capture) 파이프라인

  • Debezium + Flink CDC로 RDB → Iceberg/Hudi 같은 실시간 테이블 동기화
  • Kafka Consumer로는 CDC 이벤트 해석/머지 로직을 직접 구현해야 함

운영/확장성

  • 수십~수백 파티션, 수십억 건 데이터 실시간 처리
  • Flink는 체크포인트·세이브포인트·클러스터 확장 기능 제공

Kafka Consumer만으로 충분한 경우

단순 메시지 소비 → 저장

  • Kafka → DB insert, Kafka → S3 dump
  • Latency와 중복 크게 중요하지 않을 때

소규모 파이프라인

  • 데이터량 적고, consumer 그룹만으로 충분히 확장 가능한 경우

운영 복잡성을 피하고 싶을 때

  • Flink 클러스터 운영 부담이 크고, 팀 역량이 아직 스트리밍 운영에 익숙하지 않을 때

Kafka의 일반 소비자(Consumer API)와 Flink 이 차이점

Kafka의 일반 소비자(Consumer API) 를 직접 쓰는 것과, Flink를 Kafka 소비자로 사용하는 것은 접근 방식이 꽤 다르다.
Kafka Consumer만 쓰면 “메시지 큐 소비” 수준에서 끝난다. (주로 단순 ETL or microservice event 처리 용도)
Flink를 Kafka Consumer로 쓰면 “스트리밍 데이터 처리 엔진”이 되어,

실시간 집계, 상태 기반 처리, 이벤트 시간 기반 정렬/윈도우, Exactly-once 보장, 다양한 데이터 레이크/DB Sink와 연동이 가능해진다. 이런 고급 기능들을 Kafka → (Flink 처리) → Iceberg/DB 형태로 바로 이어갈 수 있다.

Kafka Consumer 단독 사용

  • Kafka Client API (kafka-clients) 를 애플리케이션에서 직접 사용
  • 단순한 메시지 소비/처리/저장 시에 적합
  • 장점: 가볍고 의존성 적음, Latency 최소화
  • 단점:
    • 복잡한 상태 관리 직접 구현 필요 (offset, checkpoint 등)
    • Exactly-once 보장 어렵고, 보통 At-least-once
    • 창(window), 조인(join), 집계(aggregate) 같은 스트리밍 처리 기능 없음 → 직접 구현해야 함
    • 장애 복구 시 애플리케이션 레벨에서 offset 제어 필요

📌 Flink를 Kafka Consumer로 사용할 때의 장점

구분Kafka Consumer 직접 사용Flink + Kafka Connector
Offset 관리개발자가 직접 commit 제어Flink Checkpoint/Savepoint로 자동 관리 (장애 복구 시 정확한 위치 복원)
처리 보장보통 At-least-once (Exactly-once 구현은 복잡)Exactly-once / At-least-once 선택 가능
상태 관리개발자가 Redis/DB 등에 직접 저장Flink의 State Backend (RocksDB, Memory, FileSystem, S3) 자동 관리
스트리밍 연산수동 구현 필요 (window, join, agg)Flink SQL/DSL로 네이티브 지원
CDC / Upsert직접 구현 필요Flink Table/SQL에서 UPSERT, MERGE INTO 가능
Sink 다양성직접 구현 (DB, S3, HDFS, Iceberg 등)Connector 제공 (Iceberg, Hudi, Delta Lake, Elastic, JDBC 등)
확장성Consumer Group으로 scale-out은 가능Flink 병렬성 + Operator 기반 확장 (Kafka만이 아닌 end-to-end 확장)
장애 복구수동 offset reset 필요Checkpoint/Savepoint로 자동 재처리
운영 편의성단순하지만 관리 포인트 많음Job 단위 관리 (Flink UI, Metrics, Alert 연동)

트리노로 insert 시 문제점

Trino(구 PrestoSQL)는 "읽기(쿼리 엔진)" 중심 아키텍처라서, INSERT 같은 쓰기 작업에서는 몇 가지 제약과 문제가 생긴다. Trino를 쓰기 파이프라인 도구로 쓰면 운영상 문제 많고, 읽기 전용 쿼리 엔진으로만 쓰는 게 맞다.

트랜잭션 모델 부족

  • Trino는 MPP 분산 쿼리 엔진이지만 강력한 트랜잭션 관리(ACID) 기능을 갖고 있지 않다.
  • Hive Metastore, Iceberg, Delta Lake 같은 외부 테이블 포맷에 의존해야만 어느 정도 ACID를 확보할 수 있다.
  • 단일 INSERT는 가능하지만, 다중 세션에서 동시 쓰기를 하면 충돌, 데이터 불일치가 쉽게 생긴다.

쓰기 성능 저하

  • Trino는 기본적으로 읽기 최적화 설계 → Insert/Update/Delete는 Parquet/ORC 파일을 새로 쓰고 메타데이터 갱신해야 함.
  • Spark/Flink처럼 쓰기 전용 Task Scheduler가 아니기 때문에, 대량 데이터 삽입 시 성능이 떨어진다.
  • 소량 배치 INSERT(예: dimension table)에는 괜찮지만, 대규모 fact table ingest에는 부적합.

실시간 처리 한계

  • Trino에는 Flink나 Kafka Connect처럼 실시간 ingest 파이프라인 기능이 없음.
  • Kafka 메시지를 직접 받아 테이블에 Insert하는 구조는 지원하지 않음.
  • 실시간 데이터는 보통 Flink, Kafka Connect, Spark Structured Streaming → Iceberg/Hudi/Delta로 쓰고, Trino는 조회(Query Serving Layer) 전용으로 쓴다.

운영 부담

  • Trino Insert는 작은 배치 + 메타데이터 갱신이라,
    자주 쓰면 Hive Metastore/Iceberg 메타데이터가 fragmentation 되어 쿼리 성능이 저하됨.
  • Spark/Flink는 compaction job을 통해 정리하지만, Trino는 이런 유지보수가 없다.

Trino → StarRocks 변경 (쿼리 레이어 교체), Flink 도입 (실시간/CDC ingest 강화) 고려 사항

Trino → StarRocks 변경

StarRocks는 MPP 기반 OLAP 데이터베이스이고, Trino는 분산 SQL Query Engine이라 성격이 다르다.

장점

  • 실시간 데이터 분석: StarRocks는 높은 QPS + 낮은 레이턴시 설계 (초 단위 ingest → 즉시 조회 가능).
  • Insert/Update/Delete 지원: Trino는 쓰기 약하지만, StarRocks는 RDBMS처럼 DML 지원.
  • Materialized View 자동 업데이트 → BI/대시보드 성능 최적화.
  • Colocation Join / Cost-based Optimizer → 일부 워크로드에서 Trino보다 훨씬 빠름.
  • 클러스터 단일화: Trino처럼 외부 시스템에 의존하지 않고 자체 스토리지/엔진 보유.

단점

  • 데이터 소스 통합 약화: Trino는 다양한 소스를 federated query(데이터 가상화)로 접근 가능하지만, StarRocks는 주로 자체 테이블+연결자 수준.
  • Lakehouse 친화성 부족: Iceberg/Hudi/Delta 연동은 발전 중이지만, Trino만큼 범용적이지 않음.
  • 운영 복잡성: OLAP DB이므로 스토리지 관리 + 클러스터 운영 책임이 필요.
  • 커뮤니티 생태계: Trino에 비해 상대적으로 신규(2020년 이후 급성장), 운영사례가 적음.

Flink는 스트리밍/CDC ingest 엔진으로, Trino나 StarRocks와 보완 관계.

장점

  • 실시간 데이터 처리: Kafka, MySQL/Postgres CDC, Debezium 등과 연동 → Iceberg/Hudi/Delta에 실시간 Append 가능.

  • Exactly-once 보장: Spark보다 정교한 상태 관리(State)와 체크포인트.

  • SQL 기반 스트리밍: Flink SQL로 ETL 파이프라인 작성 가능.

  • Lakehouse 연동: Iceberg/Hudi/Delta에 실시간 commit → 이후 Trino/StarRocks에서 조회 가능.

단점

  • 운영 복잡성: Flink Cluster 운영은 Spark보다 복잡(체크포인트, savepoint, HA 관리 필요).

  • 러닝 커브: 배치+스트리밍 융합 개념(Flink SQL, DataStream API)이 낯설 수 있음.

  • BI 직접 연결 어려움: Flink는 데이터 저장소가 아니라 파이프라인 엔진 → 조회용으로 바로 쓰기는 불가.

  • 카프카/CDC 의존성: Flink만으로는 소스→싱크 스트리밍이 안 되고, Kafka/DB CDC 준비가 필요.

조합 시나리오

  • Flink: 실시간 ingest (CDC → Iceberg/Hudi)
  • Trino: 데이터 소스 통합 + 분석 쿼리

장점: 데이터 가상화 + 실시간 ingest 조합

단점: Insert 성능은 여전히 Trino 한계

  • StarRocks + Flink
  • Flink: CDC ingest (DB/Kafka → StarRocks)
  • StarRocks: 초저지연 조회 + BI

장점: 진짜 Real-time OLAP 가능 (millisecond 단위 쿼리)

단점: Trino처럼 다양한 소스 통합 쿼리는 약함

0개의 댓글