Rust + Actix
So what: 메모리 안정성이 보장되고 GC가 없는 시스템 언어로 API 서버 구축
So why: AR 내비게이션은 실시간 위치 데이터를 다수의 Flutter 클라이언트에 동시에 내려줘야한다. Go나 Java 기반 서버는 GC pause가 발생하는 순간 응답 지연이 생기는데 Actix-Web은 GC 없이 Tokio 비동기 런타임 위에서 동작해서 지하철/버스 실시간 API를 동시에 여러 클라이언트에 낮은 지연으로 처리할 수 있다.
Kafka
So what: 서울 열린데이터 API에서 수집한 실시간 지하철 데이터를 Kafka 토픽으로 발행하고 Consumer가 Valkey에 저장한다
So why: 서울 열린데이터 API를 Flutter 요청마다 직접 호출하면 두 가지 문제가 생긴다. 첫 번째는 API 호출 횟수 제한, 두 번째는 클라이언트 수가 늘어날수록 외부 API 응답 속도에 직접 의존하게 되는 형상이 일어난다. Kafka로 Producer와 Consumer를 분리하면 수집은 30초 주기에 1회만 하고, Flutter 요청은 Valkey에서 바로 꺼낼줄 수 있다. 데이터 수집과 서빙을 독립시킨 구조이다
Valkey ( Cache )
So what: 경로 데이터는 5분, 실시간 지하철/버스 데이터는 30초 TTL로 캐싱한다
So why: ODSay 경로 API는 동일한 출발지/목적지 요청에 항상 같은 결과를 반환한다. 요청마다 외부 API를 호출하면 ODsay 일일 호출 한도를 빠르게 소진하게 된다. Valkey(Redis 호환)로 캐싱하면 같은 경로는 TTL 안에서 캐시에서 바로 응답하고 외부 API 호출을 최소화할 수 있다. Redis 대신 Valkey를 선택한 건 Redis의 License 변경 이후 오픈 소스 대안으로 Linux Foundation이 관리하는 프로젝트이다.
FastAPI + Python
So what: LightGBM 혼잡도 예측 모델을 별도 FastAPI 서버로 분리해서 Rust 백엔드에서 HTTP로 호출한다.
So why: Python에 ML 라이브러리가 압도적으로 풍부하다. Rust에서 ML 모델을 직접 서빙하는 건 가능하지만 학습/전처리 파이프라인까지 Rust로 구현하는 건 생산성이 너무 낮다. AI 서버를 분리하면 모델을 재학습하거나 교체할 때 Rust를 안거드려도 되고, 두 서버가 독립적으로 스케일링할 수 있다. FastAPI를 선택한 건 Pydantic 기반 요청/응답 검증과 자동 문서화가 Rust와 연동할 때 명세를 맞추기 편하기 때문이다
Kafka가 분산 처리인 이유
So what: Kafka는 데이터를 생산하는 Producer와 소비하는 Consumer를 완전히 분리한 분산 메세지 Queue이다.
So why: 기존 방식은 API 서버가 데이터를 수집하고 저장하고 서빙까지 혼자 담당한다. 트래픽이 몰릴 경우 하나의 병목이 전체를 멈추는 상황이 발생한다. Kafka는 Producer와 Consumer를 독립된 프로세스로 나눠서 각자 다른 속도로 동작이 가능하다. Prdoucer가 빠르게 쌓아도 Consumer는 자기 속도로 처리하고 Consumer를 여러 개 붙이면 같은 토픽을 병렬로 소비가능하다.
Valkey가 분산 저장인 이유
So what: Valkey는 데이터를 디스크가 아닌 메모리에 저장하는 인메모리 분산 데이터 스토어이다
So why: RDB는 디스크 I/O가 발생해서 실시간 데이터를 빠르게 읽고 쓰기에 한계가 있다. Valkey는 메모리에서 직접 읽고 써서 micro sec 단위 응답이 가능하다. 클러스터 모드에서는 데이터를 여러 노드에 샤딩해서 분산 저장하고, 특정 노드가 죽어도 복제본에서 서빙할 수 있다. 단일 노드지만 구조 자체가 분산 확장이 가능한 형태이다.
So why 빅데이터 분산 Architecture인가
So what: 수집 -> 파이프라인(Kafka) -> 고속 저장 (Valkey) -> 서빙의 레이어가 완성된다.
So why: 지하철 실시간 데이터는 서울 전체로 확장할 경우 수백 개 역, 수천 개 열차 정보가 초단위로 갱신된다. 이 규모의 데이터를 단일 서버에서 수집하고 DB에 쓰고 API로 서빙하면 어느 한 지점에서 반드시 병목 현상이 생긴다. Kafka로 수집을 병렬화하고 Valkey로 서빙을 인메모리화하면 데이터 양이 늘어도 각 레이어를 독립적으로 확장할 수 있다. (수평 확장)
'Project > SSAFY2학기 특화 PJT' 카테고리의 다른 글
| [BE] seoul.rs ( 서울 열린 데이터 광장 API ) (0) | 2026.03.13 |
|---|---|
| [BE] kakao.rs ( KAKAO API ) (0) | 2026.03.13 |
| [BE] odsay.rs ( ODSAY API 연동 ) (0) | 2026.03.13 |
| [AI] main.py ( 서버 실행 ) (0) | 2026.03.13 |
| [AI] train.py ( 모델 훈련 ) (0) | 2026.03.13 |
