← Apache Flink 코스

Courses · Day 3

핵심개념 B — 늦게 오는 데이터와 오래 유지되는 상태

스텝 7 / 17

7 / 17
개념 flink-course-07

Watermark — '언제까지 기다릴지'를 시스템이 어떻게 판단하는가

직관적으로

선생님이 시험 답안지를 걷을 때 "9시까지 낸 것만 인정"이라고 마감을 정하는 것과 비슷하다. 하지만 스트리밍 시스템은 애초에 '몇 시까지가 마감인지'조차 미리 알 수 없다 — 얼마나 늦게 오는 데이터까지 기다려줄지를 시스템이 스스로 추정해서 선언해야 한다. Watermark가 바로 이 '마감 선언'이다.

실제 사례

센서 데이터가 최대 20초까지 지연될 수 있다고 가정하자. 지금까지 관측한 가장 최신 이벤트 시각이 9:00:30이라면, watermark = 9:00:30 − 20초 = **9:00:10**으로 설정된다. 즉 "9:00:10 이전 이벤트는 이제 다 도착했다"는 선언이다. 이후에 9:00:09짜리 이벤트가 와도 "너무 늦었다"고 판단해 별도 처리(늦은 데이터 스트림으로 분기하거나 버림)된다.

정확한 원리

`WatermarkStrategy` 인터페이스는 `TimestampAssigner`(각 레코드에서 이벤트 시간을 뽑아내는 역할)와 `WatermarkGenerator`(그 시각들을 보고 watermark를 만들어내는 역할)를 함께 감싼다. 대표적으로 `WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofSeconds(20))`처럼 최대 지연 허용치를 지정해 쓴다. Watermark는 실제로 스트림 안을 흐르는 특수한 이벤트이며, **연산자는 자신에게 온 watermark를 완전히 처리한 뒤에야 다음 연산자로 전달**해야 한다는 규칙이 있다 — 이 덕분에 윈도우는 자신의 종료 시각을 넘어서는 watermark가 도착해야 비로소 "완료됐다"고 판단해 결과를 내보낸다. 입력이 여러 개인 연산자(예: 두 스트림을 조인)에서는 **각 입력 watermark 중 최솟값**이 그 연산자의 유효 watermark가 된다 — 한쪽만 빨리 진행해서 다른 쪽 데이터를 놓치는 일을 막기 위해서다.

흔한 오해

"watermark는 정확한 현재 시각을 나타낸다"는 오해가 흔한데, 사실은 **추정치이자 타협**이다. 너무 짧게 잡으면 정상적으로 늦게 온 데이터를 놓치고, 너무 길게 잡으면 그만큼 결과가 늦게 나온다(윈도우가 안 닫히니까) — 정확도와 지연시간(latency)의 트레이드오프라는 게 핵심이다.

확인 문제

지각 허용치를 `forBoundedOutOfOrderness(Duration.ofSeconds(30))`으로 설정했다가, "지각 데이터를 절대 놓치기 싫으니 60분(3600초)으로 늘려버리자"고 한다면 어떤 부작용이 생길까?