마이크로배치 vs 진짜 스트림 처리
직관적으로
배달 앱을 떠올려보자. 한 가지 방식은 '10분마다 한 번씩 그 동안 쌓인 주문을 몰아서 배달원에게 뿌리는' 방식이고, 다른 방식은 '주문이 들어오는 즉시 그 건 하나만 배달원에게 배정하는' 방식이다. 전자가 마이크로배치, 후자가 진짜 스트림 처리다. Spark Structured Streaming은 원래 배치 엔진 위에 스트리밍을 얹은 구조라 전자에 가깝고, Flink는 처음부터 후자로 설계됐다.
실제 사례
Spark Structured Streaming은 마이크로배치 트리거(기본 수백 ms~수 초 간격)로 짧은 배치 잡을 반복 실행한다 — study_de의 Spark 학습 콘텐츠에서 다룬 것처럼, 아무리 트리거 간격을 짧게 잡아도 '배치 하나를 계산하는' 단위 자체가 남아있다. Flink는 레코드 하나가 들어오면 그 즉시 연산자를 통과해 흘러간다 — 배치라는 단위 자체가 없다. 그 결과 지연시간(latency)이 근본적으로 다른 수준으로 내려간다.
정확한 원리
Flink의 런타임은 오래 실행되는(long-running) 태스크들이 파이프라인 형태로 연결돼, 레코드가 한 연산자를 통과하는 즉시 다음 연산자로 전달되는 **파이프라인 실행 모델**을 쓴다. 이는 Spark의 '배치 잡을 짧은 간격으로 반복 스케줄링'하는 마이크로배치 모델과 근본적으로 다른 실행 방식이다. Kafka Streams도 레코드 단위 처리라는 점에서는 Flink와 같은 철학이지만, Kafka Streams는 라이브러리(애플리케이션 프로세스 안에 임베드)인 반면 Flink는 별도의 실행 클러스터(JobManager/TaskManager)를 가진 범용 엔진이라는 차이가 있다.
흔한 오해
"Spark Structured Streaming도 Continuous Processing 모드가 있으니 결국 똑같은 거 아닌가?"라는 오해가 흔하다. study_de의 Spark 학습 콘텐츠에서 다뤘듯, Continuous Processing은 Spark 3.x부터 존재하는 실험적 모드로 at-least-once만 보장하고 지원 연산/소스/싱크가 극히 제한적이라 실무에서는 여전히 마이크로배치가 사실상 유일한 선택지다. 반면 Flink의 파이프라인 실행은 처음부터 기본 실행 모델이고, exactly-once까지 지원한다 — 실험 기능과 기본 아키텍처를 동일 선상에 놓고 비교하면 안 된다.
확인 문제
만약 "실시간성이 생명인 초저지연(수십 ms) 결제 이상거래 탐지" 시스템을 만든다면, Spark Structured Streaming의 기본 마이크로배치 모드로 이걸 안정적으로 달성할 수 있을까? 왜 그런지 설명해보자.
Answer Guide
마이크로배치는 트리거 간격만큼의 지연이 구조적으로 존재하고(아무리 짧게 잡아도 배치 계산 자체에 시간이 걸림), 수십 ms 수준을 '안정적으로' 보장하기는 어렵다는 요지가 들어가야 한다. Flink 같은 파이프라인 실행 모델이 이런 요구사항에 더 적합하다는 결론.
흔히 나오는 부분 정답
"Spark는 배치라서 느리다"까지만 답하는 경우가 많은데, 정확히는 '배치라서 항상 느린 게 아니라, 배치라는 단위 자체가 최소 지연시간의 하한선을 만든다'는 구조적 이유까지 짚어야 한다.