단순 기능 구현을 넘어, 서비스 운영 기준과 트레이드오프를 고민합니다.
코드 저장소: minji0828/wantbehelp-3rd-LXP · refactor/shorts
숏터디는 짧은 학습 콘텐츠를 소비하는 숏폼형 LXP(Learning Experience Platform) 지향 서비스입니다.
초기 기획 당시 추천 시스템, 마인크래프트식 뱃지 등 다양한 확장 아이디어가 논의되었으나, 가장 중요한 것은 "학습 영상의 품질 보장"이라고 판단했습니다.
이에 무분별한 콘텐츠 확장을 멈추고, 업로드 상태와 게시 가능 상태를 분리하여 콘텐츠 노출 기준을 명확히 하는 구조를 설계했습니다.
* Frontend(Next.js), 디자인, 보안 전반은 타 팀원 소관으로 본 기여도에서 제외함.
기술의 맹목적 도입이 아닌, 현재 상황에 맞는 trade-off 기반의 설계
사용자가 서버를 거치지 않고 S3에 직접 업로드하는 구조를 채택했습니다.
Direct Upload의 한계 중 하나인 '이탈 시 고아 데이터 누적(스토리지 비용 증가)'을 방지하기 위해, 업로드 세션을 발급/관리하고 실패 재시도 시 이전 세션의 찌꺼기를 정리하는 로직과 스케줄러를 구축했습니다.
* 한계점: 단, 현재 구조는 클라이언트의 완료 요청에 의존하므로 '실제 S3 객체 존재 여부'를 백엔드에서 동기적으로 100% 보장하지 못하는 아쉬움이 존재합니다.
AI 검수 기능 도입으로, 파일 업로드 완료가 곧 '공개'를 의미해선 안 됐습니다.
설계: 파일 업로드 완료 여부와 숏츠의 비즈니스 상태를 분리하여, 업로드 파이프라인과 게시/조회 정책이 섞이지 않도록 구성했습니다.
조회수는 강한 정합성보다 쓰기 경합 해소가 중요한 데이터입니다.
설계: 매 요청마다 DB를 Update하지 않고 Redis INCR로 메모리에 누적 후 주기적으로 MySQL에 지연 반영(Write-back)하여 부하를 분산했습니다.
키워드와 실시간 조회수를 조합하기 위해 복잡한 엔티티 그래프 대신, projection DTO 기반 기본 데이터 조회 + 키워드 배치(In 절) 조회 + Redis 병합으로 응답 조립 책임을 분리했습니다.
서비스 운영 중 발생할 수 있는 데이터 정합성과 인프라 문제 개선
| 영역 | AS-IS (문제 상황) | TO-BE (해결 및 설계 판단) |
|---|---|---|
| 데이터 무결성 (삭제 시 FK 충돌) |
회원 탈퇴나 숏츠 삭제 시, 연관된 자식 Row(좋아요, 댓글 등)가 남아있어 외래키 제약조건 위배로 부모 삭제(Soft Delete 포함)가 실패함. | 부모 삭제 전, 트랜잭션 내에서 FK를 직접 참조하는 자식 데이터를 먼저 Hard Delete 하도록 삭제 순서를 서비스 레벨에서 명확히 제어하여 무결성을 보장함. |
| 배포 및 인프라 (SPOF 한계) |
초기 단일 EC2 인스턴스에 App, Redis, MySQL을 모두 올려 장애 발생 시 DB 데이터까지 통째로 유실되는 치명적 문제를 겪음. | 데이터 계층을 Amazon RDS로 완전 분리하고, EC2에는 Docker Compose 기반으로 클라이언트, Redis, 백오피스 API를 나누어 배치하는 구조로 재설계. |
| 비즈니스 지표 API (BackOffice) |
업로드 수, 전환율 등 비즈니스 지표를 클라이언트에서 개별 계산하면 시간대나 산출 기준 차이로 수치 기준이 흔들릴 위험 존재. | BackOffice API 계층에서 KST 기준, 분모/분자 산출 기준, 입력 기간 처리를 정리하여 서버가 지표 계산 기준을 제공하도록 구현. |
| 영역 | 현재의 한계 (Limitations) | 추후 아키텍처 계획 (To-Be Architecture) |
|---|---|---|
| 객체 존재 검증 (S3 무결성) |
Direct Upload 후 클라이언트의 API 호출만으로 게시를 처리하여, 실제 S3에 파일이 정상적으로 존재하는지 백엔드에서 교차 검증하지 못함. | S3 Event Notification을 활용하여, 파일 업로드 완료 이벤트를 백엔드가 수신한 뒤에만 최종 '게시 가능 상태'로 전환하는 비동기 검증 파이프라인 구축. |
| 썸네일 및 미디어 후처리 |
서버(FFmpeg)에서 동기적으로 미디어를 처리하면 Direct Upload의 부하 분산 이점이 사라지며, 처리 지연 시 타임아웃 발생 우려가 있음. | 트래픽 증가에 대비하여 `S3 이벤트 → SQS(완충) → AWS Lambda` 형태의 이벤트 기반 아키텍처(EDA)로 미디어 처리를 분리하고 재시도 큐를 구성. |
| 조회수 어뷰징 (Unique View) |
무분별한 조회수 중복을 막기 위해 비회원 식별 시 IP와 User-Agent 해싱에 의존. 이는 NAT 환경 등에서 충돌 가능성이 높음. | IP 의존을 줄이고, 애플리케이션 조회수는 서버에서 발급하는 익명 UUID 쿠키 기반 식별 방식으로 고도화. |
팀 프로젝트에서의 협업 기준, AI 코드 검토, 그리고 trade-off 기록
단순한 산출물 제출이 아닌, 팀 프로젝트 전체의 구조를 설명하기 위해 PPT를 직접 제작하고 여러 발표 방식을 실험했습니다.
문서를 정리하고 발표를 준비하는 과정이 선순환되어, 단편적인 내 파트를 넘어 프로젝트 전반의 아키텍처 조감도를 깊이 이해하는 계기가 되었습니다.
시간과 체력을 갈아 넣어 무리하게 확장된 기능을 욱여넣는 것보다, 정해진 기준 안에서 명확히 설계된 핵심 기능의 완성도와 안정성이 서비스에 훨씬 더 중요하다는 것을 체감했습니다.
양으로 증명하기보다, 제대로 된 엔지니어링 기준(Trade-off 고려, 삭제 무결성, 조회수 부하 분산)을 세우는 데 집중했습니다.
기능 구현에 그치지 않고,
상태 분리, 지연 반영, 삭제 순서 제어, 운영 기준 확정처럼
실제 서비스가 버틸 수 있는 구조를 고민하는 백엔드 개발자입니다.