Introduction
이전 포스팅에서는 Spark의 RDD Streaming을 이용하여 멀티 노드 Kafka 클러스터에서 전송된 데이터를 분석하고, 실시간으로 비트코인 관련 인기 해시태그를 파악하는 과정을 소개했습니다.
이번에는 Spark Structured Streaming을 활용하여 동일한 데이터를 처리하는 방식을 다뤄보겠습니다. Structured Streaming은 RDD 기반의 처리 방식에 비해 더 높은 추상화와 간단한 API를 제공하며, 성능 최적화와 확장성 측면에서도 유리하다고 합니다.
프로젝트의 주요 목표
1. Kafka로부터 실시간 트위터 데이터를 수신 및 분석
2. 상위 30개의 인기 해시태그를 실시간으로 계산 및 출력
3. Structured Streaming의 윈도우 연산과 데이터 프레임 기반 API 활용
Kafka Producer : 데이터 스트리밍 시뮬레이션
Kafka Producer 설정은 이전 포스팅의 코드를 그대로 활용하며, 트윗 데이터를 Kafka 클러스터로 전송합니다.
Spark Structured Streaming 구성
1) Kafka 데이터 읽기
kafkaStream = spark.readStream \
.format("kafka") \
.option("kafka.bootstrap.servers", "kafka1:9092,kafka2:9092") \
.option("subscribe", "q5a") \
.load()
- Kafka 소스로부터 스트리밍 데이터를 읽어옵니다.
- kafka.bootstrap.servers: Kafka 클러스터의 브로커 주소.
- subscribe: 데이터가 있는 Kafka 토픽(q5a)을 지정.
- Kafka 메시지는 key-value 형식이며, 여기서는 value와 timestamp 필드를 사용합니다.
2) 해시태그 추출 및 필터링
hashtags_df = df \
.select(col("timestamp"), explode(split(col("value"), " ")).alias("hashtag")) \
.where(col("hashtag").startswith("#"))
- Kafka 메시지(value)를 단어 단위로 나누고 해시태그로 필터링.
- explode(split(...)): 메시지를 공백으로 나누고 각 단어를 별도 행으로 확장.
- .where(...): #로 시작하는 단어만 선택.
3) 윈도우 집계 및 정렬
windowed_counts = hashtags_df \
.groupBy(window(col("timestamp"), "300 seconds", "120 seconds"), col("hashtag")) \
.count().alias('count')
sorted_counts = windowed_counts.orderBy("window", desc("count"))
- 해시태그를 5분(300초) 윈도우로 집계하고, 2분(120초) 간격으로 슬라이딩.
- window(...): 지정된 윈도우 크기와 슬라이딩 간격으로 데이터 그룹화.
- .count(): 각 해시태그의 빈도를 계산.
- 정렬:
- orderBy: 윈도우와 해시태그 빈도(count) 기준으로 정렬
4) 스트리밍 결과 저장 및 쿼리 실행 및 상위 30개 해시태그 추출
query = sorted_counts \
.writeStream \
.queryName("test") \
.outputMode("complete") \
.format("memory") \
.start()
spark.sql("CREATE OR REPLACE TEMP VIEW temp_view AS SELECT * FROM test")
res = spark.sql("""
SELECT *
FROM (
SELECT *,
RANK() OVER (PARTITION BY window ORDER BY count DESC, hashtag ASC) AS rank
FROM temp_view
) ranked
WHERE ranked.rank <= 30
""")
res.show(n=res.count(), truncate=False)
- 결과를 메모리 내 test 테이블로 저장.
- outputMode("complete"): 전체 결과를 출력. 스트리밍 결과의 전체 상태를 지속적으로 갱신.
- format("memory"): 결과를 메모리에 저장하여 쿼리 가능.
- 메모리에 저장된 스트리밍 결과(test)를 SQL로 처리.
- RANK() OVER: 각 윈도우 내에서 해시태그 빈도(count) 기준으로 순위(rank) 부여.
- WHERE ranked.rank <= 30: 상위 30개 해시태그 선택.
- 결과 출력:

My Review
이번 과제를 진행하면서 RDD와 Spark Streaming을 비교하면서 느낀점을 정리해보았습니다.
RDD로 스트리밍 데이터를 처리했을 때는 데이터 흐름을 수동으로 설계하고, 상태 관리와 같은 부분을 명시적으로 처리해야 했습니다. 특히 시간 기반의 윈도우 처리나 상태 저장과 같은 고급 기능을 구현할 때 많은 코드가 필요했고, 이를 최적화하기도 까다로웠습니다.
반면, Spark Streaming은 RDD 위에서 동작하며, 작업들을 추상화해 제공하므로 상대적으로 간단한 코드로 동일한 기능을 구현할 수 있었습니다. 예를 들어, window() 함수를 활용해 상태를 관리하거나 시간 간격을 기준으로 데이터를 집계할 때, 코드를 작성하는 데 훨씬 적은 시간이 소요되었습니다. 그래서 확실히 Spark Streaming이 데이터를 처리하는 과정을 간소화하고 제공되는 API를 통해 쉽게 구현할 수 있어 더 직관적이고 효율적이라고 느꼈습니다. 데이터 엔지니어링 초보자의 입장에서는 실시간 데이터 처리를 처음 접할 때는 Spark Streaming을 활용하는 것이 더 적합할 것 같습니다.
'과제' 카테고리의 다른 글
| [Kafka] Spark와 Kafka로 실시간 비트코인 해시태그 분석 : RDD 활용 (3) | 2024.12.08 |
|---|---|
| [Kafka] GCP Dataproc을 활용한 멀티 노드 Kafka 클러스터 구축 (2) | 2024.12.02 |
| [Spark] RDD 를 이용한 Page Rank 구현 (2) | 2024.07.01 |
| [Project] Make K-means Clustering Program (0) | 2023.09.02 |
| [Project] Finding frequent item sets (1) | 2023.07.31 |



















