OMR 채점 서비스 스케일링 트러블슈팅
이 문서는 grading-svc의 대용량 동시 채점 처리 과정에서 발생한 연쇄 장애와 그 해결 과정을 기록합니다. 단순한 메모리 부족 문제로 시작했지만, 아키텍처 안티패턴을 발견하고 수정하는 과정까지 이어졌습니다.
배경
Lumie는 학원 운영자가 OMR(Optical Mark Recognition) 답안지를 업로드하면 자동으로 채점하는 기능을 제공합니다.
부하 시나리오:
- 사용자 1명이 한 번에 최대 200장 업로드
- 100명이 동시에 업로드 = 최대 20,000장 동시 처리
초기 스택:
Python/FastAPI + OpenCV → grading-svc
Spring Boot → 백엔드 (멀티테넌트, 결제 처리)
RabbitMQ + KEDA → 비동기 큐 및 오토스케일링
MinIO → 이미지 오브젝트 스토리지
k3s (4노드: 1 master + 3 workers) → 컨테이너 오케스트레이션
문제 정의: 600MB라는 가정
작업 시작 전 예측한 메모리 소비량은 다음과 같았습니다.
예상: 1 채점 요청 × ~600MB = 100명 동시 = 60GB → 불가능
이 수치는 OpenCV가 이미지를 처리할 때마다 라이브러리 전체를 로드한다는 잘못된 가정에서 출발했습니다. 실제로는 Python의 import 캐싱 메커니즘 덕분에 라이브러리는 프로세스 시작 시 단 한 번만 메모리에 올라갑니다.