스트림 처리 vs 배치 처리
Spark 는 Streaming 처리를 지원한다. 우선 Streaming 처리라는 것은 무한히 들어오는 새로운 데이터 셋에 대한 증분 처리라고 정의할 수 있다. 스트림 처리에서 입력되는 데이터는 시작과 끝이라는 개념이 없어서 무한하다고 표현하는 것이다. 스트림 처리와 비교가 되는 데이터 처리 방식으로는 배치 처리가 있다. 배치 처리란 고정된 입력 데이터 셋에 대해 처리하는 방식이다. 데이터가 들어오는 대로 처리하는 것이 아니라 하나의 배치로 만들어서 신규 데이터 레코드를 처리한다. 예를 들어서, A1 시간 부터 A2 까지의 처리를 한 묶음(레코드)로 묶어서 처리하고, A2 시간부터 A3 시간까지의 처리를 한 묶음으로 처리하는 방식이다.
스트림 처리와 배치처리는 다른 성격으로 분리된 것처럼 보이지만, 실제 프로덕션에서는 스트림 처리와 배치처리를 같이 활용하는 경우가 많다. 예를 들어서, 스트림 처리 되는 데이터와 배치 처리되는 데이터가 조인 되어야 하는 경우가 있을 것이다.
스트림 처리는 대기 시간이 짧고, 연산 결과를 증분적인 방식으로 생성하므로 배치 작업을 여러번 반복하는 것 보다 효율적이라는 장점이 있다. 즉, 전체 데이터를 한번에 읽어들이는 작업을 반복하지 않고도, 이전 연산 상태를 기억하고 새로운 데이터에 대해서만 증분 처리한다는 의미이다. 스트림 처리를 활용하는 사례로는 다음과 같은 경우가 있다.
- 실시간으로 리포트를 갱신하는 실시간 대시보드를 만드는 경우
- 특정 이벤트나 패턴을 탐지하는 경우 alert를 발송하는 경우
- 데이터 웨어하우스에서 데이터를 얻는 시간을 줄이기 위해 스트리밍을 사용하는 경우
하지만 스트림 처리가 가진 장점 대비 비용이 많이 든다는 단점이 있다. 따라서 고비용을 감수하고서라도 실시간 처리를 통해 이점을 얻을 수 있는 경우에 사용하는 것이 좋다.
- 스트림 처리를 위한 인프라가 필요하다. 대표적으로 Kafka/Kinesis 와 같은 스트리밍 데이터를 수집하는 인프라가 추가 비용으로 필요하다.
- 스트림 처리를 위해 Spark Application 이 지속적으로 실행되어야 하므로, 트래픽이 비정상적으로 높아지는 경우를 대비하여 여분의 리소스가 필요하다. 또한 장애가 발생하는 경우 즉시 개발자가 핸들링을 해야 할 수도 있다.
Spark Streaming vs Spark Structured Streaming
Spark 에서 제공하는 스트리밍을 처리하는 방식은 2가지이다.(Spark 3.2.0기준) Spark Streaming 와 Spark Structure Streaming (구조적 스트리밍) 방식이 있다.
1. Spark Streaming
Spark Steaming 은 DStream API (Low Level APIs) 를 기반으로 하며, Spark Structured Streaming 은 Structured API (High Level APIs) 를 기반으로 한다.
Spark Streaming 는 다음과 같은 특징이 있다.
- Spark RDD를 기반으로 처리한다. Input 도 RDD이고 처리하는 데이터도 RDD가 된다.
- Micro Batch 모드로 동작한다. 일정시간동안 새롭게 들어온 데이터를 모아서 한번에 처리하게 된다.
- DataFrame이나 Dataset 과 달리 RDD를 기반으로 작동하기 때문에 자바나 파이썬 객체와 함수에 의존적이고, 스트림 처리 엔진이 제공하는 최적화 기법을 활용하기 어렵다.
- 기본적으로 처리 시간 기준으로 동작하며 이벤트가 발생한 시간 기준으로 처리하기 위해서는 별도의 구현이 필요하다.
Spark Streaming 은 위와 같이, Input Data Stream에 대해서, batch 단위로 쪼개고 Spark Engine으로 보내서 처리하게 된다.
DStream 은 처리된 시간 기준으로 도착한 RDD의 집합이라고 할 수 있다.
2. Spark Structured Streaming
Spark Structured Streaming 는 다음과 같은 특징이 있다.
- RDD를 직접 다루지 않고 DataFrame, Dataset API 를 사용하는 만큼 더 많은 종류의 스트리밍 최적화 기술을 사용할 수 있다.
- 이벤트 시간 기반으로 데이터를 처리할 수 있다.
- Micro Batch 도 지원하며, Continuous Processing 도 지원한다.
- Micro Batch Processing : 일정시간동안 새롭게 들어온 데이터를 모아서 한번에 처리하게 된다.
- Continuous Processing : 지연 없이 바로 데이터를 처리하게 된다.
Spark Structured Streaming 는 실시간으로 들어오는 데이터를 데이터 스트림에 지속적으로 추가(append)한다.
좀 더 구체적으로, trigger interval 이 1초라고 했을 때 1초마다 새로운 input data 가 들어오게 될 것이다. 이 data는 새로운 row 로 취급되어 Input Table 에 append 된다. 결과적으로는, Result Table 에 새로운 데이터가 append 된 것이 반영되어 결과값이 업데이트 된다.
word count 의 예시로 살펴보면 다음과 같다. 새로운 단어 데이터들이 입력되었을 때 Input Table 에 새로운 단어들이 append 된다. 2초 시점을 보면 기존의 [[cat, dog], [dog, dog]] 배열에 [owl,cat] 이 append 되었다. 그리고 데이터가 처리되어, [(cat, 2), (dog, 1), (owl, 1)] 로 Result Table 이 업데이트 된 결과를 확인할 수 있다.
마지막으로, writeStream 의 output 모드로는 complete, append, update 가 있다.
complete mode 는 스트리밍 데이터 셋 전체 결과를 기록한다. 각 트리거 마다 전체 데이터 셋으로 갱신된다. 집계 연산이 포함된 쿼리에 주로 사용된다. 위의 예시 또한 전체 단어의 등장 빈도 수를 count 하는 집계 연산이 일어나므로 complete mode 로 쓰이도록 한 것이다.
from pyspark.sql.functions import explode
from pyspark.sql.functions import split
# 스트리밍 데이터 프레임 생성
df = spark \
.readStream \
.format("socket") \
.option("host", "localhost") \
.option("port", 9999) \
.load()
# 데이터 변환
words = df.select(
explode(
split(df.value, " ")
).alias("word")
)
wordCounts = words.groupBy("word").count()
# 쿼리 실행
query = wordCounts \
.writeStream \
.outputMode("complete") \
.format("console") \
.start()
# 쿼리가 실행이 끝날 때 까지 대기
query.awaitTermination()
Conclusion
- Structured Streaming 초기 스트리밍 처리 모델인 DStream 에 비해서 장점이 많다. RDD 를 기반으로 하는 Streaming 에 비해 Structured Streaming 은 DataFrame/DataSet 고수준 API 를 사용한다는 차이에서 성능적으로 더 우수하고, 배치처리와 스트리밍 처리를 매끄럽게 한다.
- Structured Streaming 은 자동적으로 스트림 데이터에 대해 증분 쿼리를 실행하므로 처리해야 할 데이터 양을 최소화하고, 자원 사용을 최적화 한다.
- Structured Streaming 은 이벤트 시간 기반으로 데이터를 처리할 수 있으며, DStream 은 기본적으로 이벤트 처리 시간이 아니라 데이터 도착 시간을 기반으로 데이터를 처리하게 된다.
Reference
'Data Engineering > Apache Spark' 카테고리의 다른 글
Spark 성능 튜닝 기법 정리 (0) | 2024.07.07 |
---|---|
[Spark] Spark JDBC 연결시 발생하는 data skew 현상 해결하기 (0) | 2024.05.10 |
[Spark] Ch.15 클러스터에서 스파크 실행하기 (0) | 2024.01.04 |
[Spark] 스파크 완벽 가이드 Ch09. 데이터 소스 (0) | 2023.11.27 |
[Spark] 스파크 완벽 가이드 04 - Ch 04. 구조적 API 개요 (0) | 2023.11.07 |