2. Kafka Consumer — Spark Structured Streaming
각 토픽의 데이터를 실시간으로 소비하며, Spark에서 가공 처리합니다. 불완전한 데이터는 Redis에 임시 저장하거나 오류 로그로 분기 처리됩니다.
처리 흐름
Kafka Topic (stock.kis or stock.yfinance)
│
▼
Spark Structured Streaming
│
├──→ Redis (실시간 캐시 / 임시 버퍼)
│ └──▶ Streamlit Dashboard
│
└──→ PostgreSQL (기술적 지표 저장)
Lambda Architecture — 왜 배치와 스트리밍을 함께 쓰나?
실시간 이동평균선(MA), RSI, 볼린저밴드를 계산하려면 당일 실시간 데이터만으로는 불가능합니다.
예를 들어 200일 이동평균선을 실시간으로 구하려면:
- 과거 199일치 종가 → Batch Layer (Airflow가 미리 수집하여 PostgreSQL에 저장)
- 오늘 현재가 → Speed Layer (Kafka로 실시간 수신)
두 데이터를 Serving Layer(Redis) 에서 결합해야 비로소 의미 있는 지표가 나옵니다. 이것이 이 프로젝트에서 람다 아키텍처를 선택한 핵심 이유입니다.

하이브리드 데이터 처리
Spark Consumer는 Kafka 실시간 데이터와 PostgreSQL 히스토리컬 데이터를 결합하여 기술적 지표를 계산합니다.
| 데이터 소스 | 레이어 | 용도 |
|---|---|---|
| Kafka (실시간) | Speed Layer | 당일 현재가, 거래량 스트리밍 |
| PostgreSQL → Redis | Batch → Serving Layer | 과거 가격 데이터 (이동평균선 등 지표 계산용 히스토리) |
실시간 기술적 지표 계산
| 지표 | 설명 | 신호 |
|---|---|---|
| RSI | 상대강도지수 | RSI ≤ 30: 과매도 / RSI ≥ 70: 과매수 |
| 볼린저밴드 | 가격 변동성 밴드 | 상단 터치: 상승 모멘텀 / 하단 터치: 반등 시도 |
| MACD | 이동평균 수렴/발산 | 히스토그램 > 0: 강세 전환 신호 |
자동 신호 감지
Spark Consumer는 기술적 지표를 계산한 뒤 아래 조건을 실시간으로 검사합니다.
- 과매수 / 과매도 감지 (RSI 기반)
- 볼린저밴드 터치 감지
- 모멘텀 변화 감지 (MACD 크로스오버)
- 이상 거래량 감지 (평균 대비 2배 이상)
신호 발생 시 Redis에 저장하고, Streamlit Dashboard에 실시간 반영됩니다.
Redis 저장 구조
| 키 패턴 | 내용 |
|---|---|
signal:{symbol} | 활성 기술적 신호 정보 |
price:{symbol} | 실시간 가격 데이터 |
indicator:{symbol} | RSI, MACD, 볼린저밴드 값 |
- TTL 관리: 신호 및 가격 데이터에 TTL 적용하여 메모리 효율 유지
- Trigger Price: 신호 발생 시점의 가격 고정값 → 단기 매매 타이밍 판단에 활용