S3 이미지 저장소 기술적 의사결정 - fitpassTeam/fitpass GitHub Wiki
S3 이미지 저장소 기술적 의사결정
개요
서비스 환경에 적합한 저장소 아키텍처를 설계하고 선택하는 기술적 의사결정을 진행
요구사항
- 헬스장 이미지 등록, 수정, 삭제 기능 지원
- 유저 프로필 이미지 등록 및 변경 가능
- 모든 이미지는 S3 등 외부 스토리지에 저장하고, DB에는 이미지의 URL만 저장
문제 정의
로컬 저장 방식의 한계
- 재배포 시 파일 유실 - 서버 재시작 또는 재배포 시 이미지 파일이 사라짐
- 서버 스케일링 시 파일 공유 불가 - 여러 인스턴스 간 파일 동기화 문제
- 운영 부담 증가 - 백업, 복원, 정적 리소스 설정 등 관리 복잡성
따라서 로컬 방식은 실제 운영 서비스에 적합하지 않다고 판단
기술 선택지 비교
저장 방식 | 장점 | 단점 | 적합성 |
---|---|---|---|
Amazon S3 | - AWS 오브젝트 스토리지- 확장성 뛰어남- URL 접근 쉬움- 백업/보안 기능 우수 | - 설정 복잡- AWS 요금 발생 | ⭐⭐⭐⭐⭐ |
로컬 서버 디렉토리 | - 개발 초기 구현 간단- 무료 | - 서버 용량 문제- 배포 시 이미지 유실- 확장성 낮음 | ⭐⭐ |
Firebase Storage | - 무료 티어 있음- 모바일 친화적 | - Firebase 학습 필요- S3보다 설정 제한적 | ⭐⭐⭐ |
Cloudinary | - 이미지 CDN + 관리 기능- URL 자동 최적화 | - 일정 이상 사용 시 요금 발생 | ⭐⭐⭐⭐ |
Base64 DB 저장 | - 서버 없이 처리 가능 | - 성능 저하- DB 부하 심함 | ⭐ |
S3 업로드 방식 비교
1. 서버 중계 업로드 방식 (현재 구현)
클라이언트 → 서버 (MultipartFile) → S3
장점
- Spring의
@RequestPart
,MultipartFile
등을 통해 구현이 간단하며 직관적 - 파일 업로드와 함께 사용자 인증, 요청 유효성 검사 등의 로직을 서버 측에서 통합적으로 처리
- 작은 이미지나 관리자가 업로드하는 파일 등에 적합한 구조
단점
- 파일이 서버를 거치기 때문에 네트워크 트래픽과 서버 리소스(CPU, 메모리) 소모가 큼
- 대용량 파일을 여러 사용자가 동시에 업로드할 경우 서버 부하 급증
- 업로드 과정에서 서버가 병목 지점이 되어 응답 속도 지연 발생
2. Presigned URL 방식 (향후 적용 예정)
클라이언트 → 서버 (URL 발급) → 클라이언트 → S3 (직접 업로드)
장점
- 클라이언트가 직접 S3로 업로드하기 때문에 서버 트래픽이 거의 발생하지 않고 성능 크게 향상
- 서버는 URL만 발급하면 되므로 리소스 소모가 적고 확장성이 뛰어남
- Presigned URL에 만료 시간, 권한 범위 등을 지정하여 보안 관리 가능
단점
- 클라이언트에서 PUT 요청을 직접 처리해야 하므로 프론트엔드 구현 복잡도 증가
- 업로드 실패, 재시도 처리 등의 로직을 클라이언트에서 구현 필요
- URL 노출 시 보안 위험 있어 만료시간 관리 중요
3. Multipart Upload API
클라이언트 → 서버 → S3 (파일 분할 병렬 업로드)
장점
- 대용량 파일도 효율적으로 업로드 가능, 병렬 처리로 속도 최적화
- 업로드 중단 시 이어서 재시도할 수 있는 기능 내장
- 업로드 중간에도 부분 확인, 취소, 검증 가능
단점
- 구현이 복잡 (파트 분할, 병렬 업로드, 파트 조립 등)
- 일반적인 이미지 업로드에는 과한 방식 (주로 영상, 백업 파일용)
최종 선택 및 근거
현재 구현: 서버 중계 업로드 방식
선택 이유
- 백엔드와 프론트엔드를 혼자 개발하는 상황에서 통합적인 처리가 유리
- 이미지 업로드와 동시에 사용자 인증, 요청 유효성 검사 등을 서버에서 일괄 처리
- Spring에서 기본 제공하는 기능만으로 안정적이고 간단한 구현 가능
현재 구조의 한계점
- 서버를 통한 이미지 전송으로 인한 트래픽 및 리소스 소모
- 대용량 파일이나 동시 업로드 시 서버 병목 가능성
향후 계획: Presigned URL 방식 전환
남은 프로젝트 기간 동안 Presigned URL 방식으로 전환할 계획입니다.
기대 효과
- 서버 트래픽 및 리소스 부담 감소
- 이미지 업로드 속도 향상
- 서버 코드 단순화 (파일 I/O 제거)
- 보안성 확보 (만료 시간과 권한이 제한된 URL 사용)
기술 구현 세부사항
S3 설정
- IAM 권한 설정: 최소 권한 원칙에 따른 접근 제어
- 버킷 정책: 퍼블릭/프라이빗 권한 설정
- 보안: CORS 설정, 접근 로그 관리
Spring Boot 통합
@RequestPart("file") MultipartFile file
// → InputStream 변환 → S3 업로드
학습 회고
이번 기능 구현은 단순히 "파일을 업로드하는 기능"을 넘어, 서비스의 배포 환경과 장기적인 확장성을 고려한 기술적 의사결정의 과정이었다.
주요 학습 포인트
- 운영 환경 고려의 중요성: 로컬 저장의 한계를 인식하고 클라우드 스토리지의 필요성 이해
- 성능과 복잡성의 트레이드오프: 현재 요구사항에 맞는 적절한 수준의 기술 선택
- 단계적 개선 계획: 현재는 안정성 우선, 향후 성능 최적화로 진화하는 접근법
향후 개선 방향
Presigned URL 도입을 통해 더욱 성능적이고 확장 가능한 구조로 개선될 것으로 기대됨