Ⅰ. 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 |
'빅데이터(Big Data)' 카테고리의 다른 글
| 실시간 이벤트 스트리밍의 심장, Apache Kafka에 대해 알아보겠습니다. (0) | 2026.05.02 |
|---|---|
| 빅데이터 분석의 새로운 표준, 'DuckDB'에 대해 알아보겠습니다. (0) | 2026.05.01 |
| 중앙 집중의 한계를 깨다 분산형 데이터 혁신, 데이터 메쉬(Data Mesh) (0) | 2026.04.08 |
| 데이터 늪을 보물창고로 '데이터 레이크하우스'와 Apache Iceberg 에 대해 알아보겠습니다. (0) | 2026.03.30 |
| 데이터 늪(Data Swamp)에 대해 알아보겠습니다. (0) | 2026.01.13 |