Soundmind · MX Team Lead · 2025.02 - Present
ODIYA (Location)
외주사 코드의 DB 부하 사태(MySQL CPU 포화)를 Redis 버퍼 + 주기 배치 + 일자 파티션 구조로 재설계해 DB 쓰기 부하 ~95%를 줄이고, 인프라 증설 없이 운영을 안정화했습니다.
개요
사운드마인드 합류 후 첫 프로젝트로 오디야를 맡았습니다. 외주사가 만든 부모-자녀 위치 공유 서비스(OEM 사전탑재 채널 포함)를 팀장으로서 리딩하며 위치 파이프라인 전체를 다시 설계했습니다.
마주한 문제
외주사 코드는 자녀 단말 좌표 송출마다 JPA save() 단건 INSERT를 호출했고, 같은 흐름에서 안전구역 평가 SQL까지 누적돼 MySQL CPU가 포화 수준에 도달했습니다. 즉 "몰아치는 쓰기"와 "사용자마다 최신 좌표 한 건이면 충분한 읽기"가 같은 경로에서 직렬로 돌고 있었습니다. 단말 수 × 송출 빈도가 선형으로 늘어 인프라 증설 외에는 길이 보이지 않던 시점이었습니다.
풀이 가설
들어오는 좌표는 짧은 시간에 몰아치는 쓰기 부하지만, 안전구역 판정은 사용자마다 가장 최근 좌표 한 건만 보면 됩니다. 들어오는 좌표를 그때그때 DB에 박을 필요가 없으니, 이미 운영 중인 Redis를 추가 자원 없이 버퍼로 재활용할 수 있다고 판단했습니다.
검토한 대안
Kafka/SQS는 영구 로그·재처리·다중 컨슈머가 매력적이지만 운영 인력과 인프라 추가 부담이 컸고, DB-only 최적화는 절대량 한계가 명확했습니다. 외주사 인계 직후라 "새 자원 추가 없음"이 결정 축이었고, 운영 중인 Redis를 재활용하는 버퍼+배치 구조가 도메인 접근 패턴과 운영 비용 양쪽에 가장 잘 맞았습니다.
| 후보 | 장점 | 단점 |
|---|---|---|
| Kafka / SQS | 영구 로그·재처리·다중 컨슈머 | 운영 인력·인프라 추가 |
| DB-only 최적화 | 새 자원 0 | 절대량 한계 (파티션만 부분 채택) |
| ★ Redis 버퍼 + 주기 배치 | 기존 인프라 재활용 + 도메인 fit | Sentinel 없으면 SPOF |
선택과 근거
Redis를 두 갈래로 활용했습니다. write는 큐 버퍼에 push한 뒤 주기 배치로 DB에 적재하고, read는 캐시 hit으로 흡수합니다. DB는 일자 단위 파티션으로 모델링하고 다음날 파티션 생성과 오래된 파티션 삭제를 자동화했습니다. 단일 Redis는 의도된 절충이며, 트래픽 임계치가 넘어가면 Sentinel/Cluster로 옮길 경로는 모니터링으로 열어두었습니다.
구현과 시행착오
처음부터 "버퍼 + 배치" 개념으로 직진했고, 다른 형태로 갔다가 옮긴 시행착오는 없었습니다. 운영 중에는 자녀 단말의 GPS 신호가 튀는 케이스(짧은 시간 안에 비현실적인 거리만큼 좌표가 점프하는 현상)가 안전구역 평가를 왜곡시키는 문제가 보여, 짧은 시간에 비현실적인 거리 이동이 잡히면 안전구역 평가를 건너뛰는 보조 규칙을 추가했습니다.
성과
MySQL CPU 포화 사태가 해소되어, 인프라 증설 없이 운영이 안정화됐습니다. DB 쓰기 부하는 분당 INSERT 기준 약 95% 감소했고, 이 안정화가 OEM 사전탑재 채널 확장의 전제가 되어 회사 B2B 매출 약 230% 성장에 기여했습니다.
재설계 전후 DB 쓰기 부하 비교 (정규화 100 기준 — Redis 버퍼 + 60초 배치 적용 후 약 5 수준).
다른 프로젝트