본문 바로가기
빅데이터(Big Data)

진정한 실시간 스트림 처리의 표준, Apache Flink에 대해 알아보겠습니다.

by forward error correction Circle 2026. 5. 6.
반응형

Ⅰ. Apache Flink 란?

 Apache Flink(아파치 플링크)는 2014년 베를린 공대의 Stratosphere 프로젝트에서 파생되어 Apache Software Foundation의 Top-Level 프로젝트로 승격된 오픈소스(Apache 2.0) "스트림 우선(Stream-First)" 분산 처리 엔진입니다. 이벤트 단건을 처리하는 "진짜 스트리밍" 방식을 기반으로 하면서도, 유한한 데이터(Bounded)를 "경계가 정해진 스트림"으로 다루어 배치(Batch) 처리까지 하나의 런타임에서 통합한다는 점이 가장 큰 특징입니다. 알리바바가 "Blink"라는 자체 분기를 만들어 광군제 트래픽을 처리한 경험을 본류에 환원하면서 급성장했고, 현재는 Uber·Netflix·Lyft·Pinterest·카카오·네이버·쿠팡 등이 실시간 결제 이상탐지, 동적 요금 계산, 추천 피드, 로그·보안 이벤트 분석 파이프라인의 기반으로 사용하고 있습니다. 특히 2025년 10월 공개된 Flink 2.0은 "Disaggregated State"와 새로운 ForSt 상태 백엔드를 통해 클라우드 네이티브 시대의 상태 저장 스트리밍을 재정의하며, Spark Structured Streaming·Kafka Streams 대비 "밀리초 지연 + 정확히 한 번(Exactly-Once) 처리"를 동시에 달성하는 사실상의 표준이 되었습니다.

 

■ Flink가 해결하는 실시간 처리의 난제

실시간 처리의 난제 기존 프레임워크의 한계 Flink의 해결 방법
밀리초급 저지연 마이크로 배치(Spark) 구조상 100ms~수 초 지연 이벤트 단건 파이프라인으로 10~50ms 처리
정확히 한 번(Exactly-Once) 장애 복구 시 중복·누락 발생, 외부 저장소와 불일치 분산 스냅숏(Chandy-Lamport)으로 상태+소스+싱크 일괄 보장
이벤트 시간 처리 처리 시각 기반으로 늦게 도착한 데이터 오염 이벤트 타임 + 워터마크로 지연 이벤트 정확 집계
대규모 상태 관리 메모리 기반 상태가 GB를 넘기면 OOM·지연 폭증 RocksDB·ForSt + 증분 체크포인트로 TB급 상태 관리
배치+스트리밍 이원화 람다 아키텍처로 동일 로직을 이중 구현 단일 DataStream/Table/SQL API로 Batch+Streaming 통합
운영 탄력성 정적 병렬도, 재배포 시 장기간 다운타임 Reactive/Adaptive Scheduler로 무정지 스케일링

Ⅱ. Apache Flink 주요 특징

 ⅰ. 진짜 스트리밍(Streaming-First) 모델

   : 이벤트 단건을 DAG(Directed Acyclic Graph) 파이프라인으로 흘려보내며, 중간 셔플에서도 블로킹 없이 지속 처리합니다. 동일 엔진이 경계 있는(Batch) 데이터도 같은 방식으로 처리해 "Batch는 Streaming의 특수한 경우"라는 철학을 구현합니다.

 ⅱ. 정확히 한 번(Exactly-Once) End-to-End

   : Chandy-Lamport 알고리즘 기반의 비동기 분산 스냅숏과 2PC(Transactional Sink)를 결합해, 카프카·JDBC·Iceberg·Paimon 같은 외부 싱크까지 한 번만 기록되도록 보장합니다. 장애가 나더라도 마지막 성공 체크포인트에서 자동 복구됩니다.

 ⅲ. 이벤트 시간(Event-Time)과 워터마크(Watermark)

   : 처리 시각이 아닌 "사건이 실제 발생한 시각"을 기준으로 윈도우를 정의하고, 워터마크로 지연 허용 수준을 선언합니다. 네트워크 지연·배치 업로드처럼 순서가 뒤집힌 이벤트도 정확히 집계합니다.

 ⅳ. 대규모 키드 상태(Keyed State)

   : ValueState·ListState·MapState·ReducingState 등 다양한 상태 추상을 제공하며, RocksDB·ForSt 백엔드로 TB급 상태를 로컬 디스크·객체 스토리지에 투명하게 저장합니다. 증분(Incremental) 체크포인트로 복구 시간을 극적으로 단축합니다.

 ⅴ. 다층 API(Layered API)

   : 고수준의 Flink SQL·Table API에서 시작해, 복잡한 상태·타이머 제어가 필요할 때는 DataStream API·ProcessFunction, 극한 성능이 필요할 때는 Stateful Functions와 Async I/O까지 내려갈 수 있는 "아래로 열린" API 구조를 제공합니다.

 ⅵ. CEP·ML·Graph 라이브러리

   : FlinkCEP(복합 이벤트 처리), Flink ML(실시간 모델 서빙·피처 스토어), Gelly(그래프 분석) 등 도메인 라이브러리를 내장해 사기 탐지, 추천, 실시간 스코어링 같은 분석을 단일 엔진으로 구현합니다.

 ⅶ. 클라우드 네이티브(2.0 이후 Disaggregated State)

   : Flink 2.0부터 컴퓨트 노드와 상태 저장소를 분리할 수 있는 ForSt 상태 백엔드가 GA되어, 상태를 S3·OCI·GCS에 두고 TaskManager를 탄력적으로 확장·축소할 수 있습니다. Kubernetes Operator와 결합하면 재기동 없이 병렬도를 변경할 수 있습니다.

 ⅷ. 풍부한 커넥터 생태계

   : Kafka·Pulsar·Kinesis·Pub/Sub 같은 메시지 버스와 Iceberg·Paimon·Hudi·Delta Lake 같은 레이크하우스, JDBC·CDC(Debezium)·Elasticsearch·Redis·MongoDB 등 수십 종의 공식 커넥터를 제공합니다.

Ⅲ. Apache Flink 동작 방식

 Flink는 "JobGraph 제출 → 병렬 실행 그래프 배치 → 지속적 데이터 스트림 처리 → 주기적 스냅숏"이라는 네 단계 루프로 동작합니다. 각 단계는 JobManager와 TaskManager가 분업하며, 상태와 체크포인트가 결합해 장애 상황에서도 정확성을 유지합니다.

단계 구분 동작 상세 설명
1 Job 제출 (Submission)  JobGraph 생성 클라이언트(SQL/DataStream)가 논리적 DAG를 JobGraph로 컴파일 후 Dispatcher에 제출 → Dispatcher가 JobMaster 생성 및 실행 관리
2 Job 제출 (Submission)  리소스 할당 ResourceManager가 TaskManager 슬롯을 할당 (YARN / Kubernetes / Standalone 환경별 동적 할당 방식 차이 존재)
3 실행 그래프 (Execution) ExecutionGraph 생성  JobMaster가 JobGraph를 병렬도 기준으로 확장 → ExecutionGraph 생성 후 서브태스크를 슬롯에 배치
4 실행 그래프 (Execution)  데이터 교환 서브태스크 간 데이터 전달 (Forward / Rebalance / KeyBy / Broadcast) + 네트워크 버퍼 기반 파이프라인 처리 + Credit-Based Flow Control로 Back-pressure 제어
5 스트림처리 (Processing) 이벤트 + 워터마크 처리 이벤트 / 워터마크 / 타이머 기반 상태 처리 → 워터마크 기준으로 윈도우 연산 결과 방출 (지연 데이터 허용)
6 스트림 처리 (Processing) 비동기 I/O 외부 DB/API 호출 시 Async I/O 활용 → 이벤트 순서 유지 + Non-blocking 병렬 처리
7 체크포인트 (Checkpoint) 배리어 주입 CheckpointCoordinator가 소스에 Barrier 주입 → 스트림을 따라 전파되며 상태 스냅샷 트리거
8 체크포인트 (Checkpoint) 원격 저장 상태 스냅샷을 S3/HDFS/OSS 등에 비동기 저장 → 완료 시 체크포인트 확정 → 장애 시 Exactly-Once 복구
9 운영 제어 (Control) Savepoint / 재스케일 Savepoint 생성 후 병렬도 변경 및 재배포 가능 → Adaptive Scheduler로 무중단 확장/축소 지원

Ⅳ. Apache Flink 아키텍처 구성 및 흐름도

 ⅰ. Flink 전체 아키텍처

ⅱ. 주요 구성 요소

구성 요소 역할 비고
Flink Client SQL·DataStream 프로그램을 JobGraph로 컴파일해 Dispatcher에 전송 CLI(flink run), SQL Client, REST API, Application Mode
JobManager Dispatcher·ResourceManager·JobMaster·CheckpointCoordinator를 포함하는 제어 평면 HA 모드 시 ZooKeeper/Kubernetes에 리더 메타 저장
TaskManager 실제 오퍼레이터 서브태스크를 실행하는 워커, "슬롯" 단위로 리소스 분할 슬롯 공유로 메모리·CPU 효율 극대화
State Backend 키드 상태를 저장하는 로컬 엔진(HashMap/RocksDB/ForSt) 2.0부터 ForSt(Disaggregated)가 클라우드 기본값
Checkpoint Storage 스냅숏을 영구 저장하는 원격 스토리지 S3·HDFS·GCS·Azure Blob·OSS 공식 지원
Source / Sink Connector 메시지 버스·레이크하우스·DB와의 통합 인터페이스(FLIP-27/FLIP-143 기반) Kafka·Pulsar·Iceberg·Paimon·JDBC·CDC 등
Flink SQL Gateway REST/JDBC 기반 SQL 인터페이스 서버 BI 도구·메타스토어(Hive, Glue) 통합
Web UI / Metrics Job 상태, Back-pressure, Watermark, Checkpoint 히스토리 시각화 Prometheus·Datadog·OpenTelemetry Exporter 내장

 

 ⅲ. 배포 모드 비교

배포 모드 구성 장점 고려 사항
Session Cluster 하나의 클러스터에 여러 Job 을 제출 리소스 공유, 학습·PoC 적합 JobManager 장애 시 전체 Job 영향
Per-Job(레거시) Job 마다 JobManager 1개를 띄움 장애 격리, 단순 1.15 이후 Depercated, Application 모드 권장
Application Mode 클라이언트 없이 Job Manager가 메인 클래시 실행 프로덕션 표준, 제출 오버헤드 제거 이미지·의존성 관리 필요
Kubernetes Operator FlinkDeployment CRD 기반 선언형 배포 GitOps·Autoscaling·무중단
업그레이드
Operator·CRD 버전 호환성 관리

Ⅴ. Apache Flink 설치 방법

 학습·PoC는 로컬 Standalone(tar 압축 해제) 또는 Docker로, 운영은 Kubernetes Operator나 관리형 서비스(Amazon MSF, Ververica Cloud, Aliyun Realtime Compute)를 권장합니다. JobManager HA와 체크포인트용 원격 스토리지(S3/HDFS)는 필수로 준비하세요.

전제 조건: Java 11/17 LTS, Linux(RHEL 8+/Ubuntu 22.04+) 또는 macOS, 4코어 · 8GB RAM 이상(운영 16코어 · 32GB+). 체크포인트 저장소로 S3/HDFS/GCS 중 하나가 있어야 합니다. 대규모 상태를 쓸 경우 NVMe SSD와 10GbE 이상 네트워크를 권장합니다.

ⅰ. 로컬 Standalone 설치(가장 빠른 체험)

# 1) 바이너리 다운로드 및 해제
curl -LO https://dlcdn.apache.org/flink/flink-2.0.0/flink-2.0.0-bin-scala_2.12.tgz
tar -xzf flink-2.0.0-bin-scala_2.12.tgz
cd flink-2.0.0

# 2) 클러스터 기동(로컬 JobManager 1 + TaskManager 1)
./bin/start-cluster.sh

# 3) Web UI 확인 → http://localhost:8081

# 4) 예제 Job 제출(WordCount)
./bin/flink run examples/streaming/WordCount.jar

# 5) 종료
./bin/stop-cluster.sh

ⅱ. Docker Compose(JobManager + TaskManager)

# docker-compose.yml
services:
  jobmanager:
    image: flink:2.0.0-scala_2.12-java17
    command: jobmanager
    ports: ["8081:8081"]
    environment:
      FLINK_PROPERTIES: "jobmanager.rpc.address: jobmanager"
  taskmanager:
    image: flink:2.0.0-scala_2.12-java17
    depends_on: [jobmanager]
    command: taskmanager
    scale: 2
    environment:
      FLINK_PROPERTIES: |
        jobmanager.rpc.address: jobmanager
        taskmanager.numberOfTaskSlots: 4

# 기동
docker compose up -d
docker compose exec jobmanager flink list

ⅲ. Kubernetes Operator(프로덕션 권장)

# 1) Cert-Manager 설치(Operator Webhook 전제)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

# 2) Flink Kubernetes Operator 설치
helm repo add flink-operator https://downloads.apache.org/flink/flink-kubernetes-operator-1.10.0/
helm install flink-operator flink-operator/flink-kubernetes-operator \
  -n flink-system --create-namespace

# 3) FlinkDeployment 선언형 배포
cat <<EOF | kubectl apply -f -
apiVersion: flink.apache.org/v1beta1
kind: FlinkDeployment
metadata:
  name: orders-etl
spec:
  image: flink:2.0.0
  flinkVersion: v2_0
  jobManager: { resource: { cpu: 1, memory: 2048m } }
  taskManager: { resource: { cpu: 2, memory: 4096m } }
  job:
    jarURI: local:///opt/flink/usrlib/orders-etl.jar
    parallelism: 4
    upgradeMode: savepoint
EOF

ⅳ. HA·체크포인트 핵심 설정(flink-conf.yaml)

execution.checkpointing.interval: 30 s
execution.checkpointing.mode: EXACTLY_ONCE
execution.checkpointing.timeout: 10 min
state.backend: forst  # 또는 rocksdb / hashmap
state.checkpoints.dir: s3://my-flink/ckpt
state.savepoints.dir: s3://my-flink/sp
high-availability.type: kubernetes  # zookeeper 가능
high-availability.storageDir: s3://my-flink/ha
restart-strategy.type: exponential-delay

Ⅵ. Apache Flink 사용 방법

실무에서 가장 많이 쓰이는 네 가지 패턴 "Flink SQL로 실시간 집계", "DataStream API로 Kafka→Iceberg ETL", "CEP로 이상 패턴 탐지", "Savepoint 기반 재배포"를 살펴봅니다.

ⅰ. Flink SQL로 Kafka → 실시간 집계(가장 쉬움)

-- SQL Client 진입: ./bin/sql-client.sh
CREATE TABLE orders (
  order_id   STRING,
  user_id    BIGINT,
  amount     DECIMAL(10,2),
  country    STRING,
  event_time TIMESTAMP_LTZ(3),
  WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
  'connector' = 'kafka',
  'topic' = 'orders',
  'properties.bootstrap.servers' = 'kafka:9092',
  'format' = 'json',
  'scan.startup.mode' = 'latest-offset'
);

-- 1분 텀블링 윈도우로 국가별 매출
SELECT
  window_start, country, SUM(amount) AS revenue
FROM TABLE(
  TUMBLE(TABLE orders, DESCRIPTOR(event_time), INTERVAL '1' MINUTE)
)
GROUP BY window_start, country;

 

ⅱ. DataStream API: Kafka → 변환 → Iceberg 싱크

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.enableCheckpointing(30_000L, CheckpointingMode.EXACTLY_ONCE);

KafkaSource<Order> source = KafkaSource.<Order>builder()
  .setBootstrapServers("kafka:9092")
  .setTopics("orders")
  .setValueOnlyDeserializer(new OrderDeserializer())
  .setStartingOffsets(OffsetsInitializer.latest())
  .build();

DataStream<Order> stream = env.fromSource(source,
  WatermarkStrategy.<Order>forBoundedOutOfOrderness(Duration.ofSeconds(5))
    .withTimestampAssigner((o, ts) -> o.eventTime),
  "kafka-orders");

stream.filter(o -> o.amount > 0)
     .keyBy(o -> o.country)
     .window(TumblingEventTimeWindows.of(Time.minutes(1)))
     .reduce((a, b) -> a.merge(b))
     .sinkTo(IcebergSink.forRowData(...).table(myTable).build());

env.execute("orders-etl");

 

ⅲ. FlinkCEP로 5분 내 3회 결제 실패 탐지

Pattern<Payment, ?> fraud = Pattern.<Payment>begin("fail1")
    .where(new FailedCondition())
    .times(3)
    .within(Time.minutes(5));

PatternStream<Payment> ps = CEP.pattern(payments.keyBy(p -> p.userId), fraud);
ps.select(matches -> new Alert(matches.get("fail1").get(0).userId,
  "3 consecutive failures in 5 minutes"))
  .sinkTo(kafkaAlertSink);

 

ⅳ. Savepoint 기반 무중단 재배포

# 1) 안전하게 Savepoint 저장 후 Job 종료
flink stop --savepointPath s3://my-flink/sp <jobId>

# 2) 코드 수정·배포 후 동일 Savepoint에서 재시작
flink run -s s3://my-flink/sp/savepoint-xxx \
  -p 8 \  # 병렬도 변경
  --allowNonRestoredState \  # 오퍼레이터 구조 변경 허용
  orders-etl-v2.jar

Ⅶ. Apache Flink 자주 쓰는 명령어

 Flink의 "flink" CLI는 Job 제출·취소·Savepoint 관리·설정 조회 등 대부분의 운영을 커버합니다. Web UI가 열리지 않는 CI/CD·원격 환경에서 특히 유용합니다.

구분 명령어 설명
클러스터 ./bin/start-cluster.sh / stop-cluster.sh 로컬 Standalone 클러스터 기동·종료. 로그는 log/flink-*.log 에 남습니다.
./bin/jobmanager.sh start / taskmanager.sh start 개별 컴포넌트를 수동으로 기동(HA·멀티노드 구성 시 사용).
./bin/sql-client.sh 대화형 Flink SQL 클라이언트. -i init.sql 로 초기 스크립트 로드 가능.
./bin/historyserver.sh start 종료된 Job의 실행 이력을 조회하는 History Server.
Job 관리 flink run [-d] [-p N] [--class MyApp] app.jar Job 제출. -d 는 detached, -p 는 병렬도, --class 는 메인 클래스 지정.
flink list [-a] 실행 중(또는 전체) Job 목록을 JobID와 함께 출력합니다.
flink cancel <jobId> Job을 즉시 취소. 상태 손실을 원하지 않는다면 stop으로 Savepoint를 먼저 찍으세요.
flink stop --savepointPath s3://... "Graceful" 종료 + Savepoint 생성. 운영 배포의 사실상 표준
Savepoint / 체크포인트
flink savepoint s3://bucket/sp 실행 중 Job을 유지한 채 Savepoint만 저장(롤백 포인트 확보용).
flink run -s s3://.../savepoint-xxx app.jar Savepoint에서 복구하며 Job 재시작. 마이그레이션·재스케일 시 사용.
flink savepoint --dispose s3://.../savepoint-xxx Savepoint를 안전하게 삭제(로드되지 않은 상태 정리).
운영·진단
flink info app.jar JobGraph의 최적화된 실행 계획(JSON)을 출력. 기동 전 구조 검증에 유용.
curl http://jm:8081/jobs/<id>/checkpoints REST API로 체크포인트 상태·지연·크기를 조회합니다.
kubectl describe flinkdeployment <name> Kubernetes Operator 환경에서 FlinkDeployment 상태·이벤트를 확인합니다.
SQL·Table
SHOW TABLES; / DESCRIBE orders; Catalog에 등록된 테이블 목록과 스키마를 조회합니다.
EXPLAIN PLAN FOR SELECT .. Flink SQL 쿼리의 논리/물리 실행 계획을 출력합니다.
SET 'execution.checkpointing.interval' = '30s'; SQL 세션에서 체크포인트·병렬도 등 런타임 파라미터를 즉시 반영합니다.

 

Ⅷ. Apache Flink 활용 방안

 Flink는 "데이터가 생기는 즉시 의사결정"을 해야 하는 모든 도메인에서 기본 엔진으로 자리잡았습니다. Kafka·Iceberg·ClickHouse와 결합하면 "스트리밍 레이크하우스" 아키텍처를 표준화할 수 있습니다.

활용 분야 주요 유스케이스 Flink 적용 포인트 대표 사례
실시간 이상탐지 결제·로그인·봇 탐지 FlinkCEP로 N초 내 M회 실패 같은 시간적 패턴을, Keyed State로 사용자·장치별 행동 누적을 분석해 수십 ms 안에 차단 결정을 내립니다. 네이버 페이, Lyft Marketplace
동적 가격·추천 차량 호출·e커머스 이벤트 시간 기반 수요·공급 집계를 초 단위로 수행하고, Flink ML로 경량 모델을 온라인 재학습·서빙하여 가격과 추천 피드를 갱신합니다. Uber Surge, Alibaba Tmall
스트리밍 ETL / CDC 운영 DB → 분석 레이어 Debezium·Flink CDC로 MySQL·PostgreSQL·MongoDB의 변경 로그를 읽어 Iceberg·Paimon·ClickHouse·Elasticsearch로 초 단위 반영합니다. Flink CDC + Paimon 레이크하우스
IoT·제조 센서·설비·차량 MQTT·Kafka를 통해 들어오는 고빈도 시계열을 이벤트 시간으로 정렬하고, 윈도우 통계·SLA 위반을 실시간 경보로 변환합니다. 현대자동차 커넥티드카, BMW Smart Plant
실시간 관측성(Observability) 로그·트레이스 가공 OpenTelemetry·Filebeat로 수집한 원천 신호를 Flink로 정제·라우팅해 ClickHouse·ElasticSearch·S3 등 목적별 저장소로 분기합니다. Pinterest Observability, Shopify Logs
SIEM·보안 이벤트 UEBA·위협 헌팅 EDR·방화벽 로그를 키드 윈도우로 세션화하고, CEP로 다단계 공격 패턴을 탐지해 SOAR 플레이북을 자동 트리거합니다. Capital One SIEM, LINE Security
스트리밍 레이크하우스 Iceberg·Paimon·Hudi Exactly-Once 싱크로 레이크하우스 테이블을 분 단위 최신 상태로 유지하고, 동일 테이블을 배치 분석에도 사용해 람다 아키텍처를 제거합니다. Apple Iceberg Platform, 쿠팡 Paimon
AI 실시간 피처·RAG 온라인 피처·임베딩 업데이트 Flink ML과 Async I/O로 최신 사용자 피처를 Feature Store(Feast 등)에 밀어 넣고, 스트리밍 이벤트를 실시간으로 임베딩해 RAG 벡터DB를 갱신합니다. Stripe Radar, OpenAI Online Features
반응형