[Spring Boot] AWS S3 bucket을 이용한 image upload - 이론

Hood·2025년 8월 18일

Spring Boot

목록 보기
13/15
post-thumbnail

✍ Back-End 지식을 늘리자!

백엔드 개발자를 준비하면서 생긴 궁금증을 정리한 포스트입니다.


들어가기 전

프로젝트를 진행하다가 디자인팀의 피그마를 보던 중,
사용자의 프로필 이미지를 업로드하고 관리해야 하는 기능이 필요해졌습니다.

이때 가장 먼저 들었던 고민은
“이미지를 어디에 저장하고, 어떻게 불러와서 사용할 수 있을까?”였습니다.

그래서 온라인 객체 스토리지 서비스를 떠올리게 되었고,
그중 AWS의 S3를 사용해 이미지를 업로드하는 방식을 정리해보려고 합니다.


1. 온라인 객체 스토리지(Online Object Storage)란?

온라인 객체 스토리지는 데이터를 객체(Object) 형태로 저장하는 서비스입니다.
대표적으로 사진, 영상, 문서 같은 파일을 저장하고,
필요할 때 네트워크를 통해 다시 불러올 수 있습니다.

Amazon S3 역시 이런 객체 스토리지 서비스 중 하나이며,
AWS는 S3를 대규모 확장성과 높은 내구성을 제공하는 객체 스토리지 서비스로 설명하고 있습니다. (Amazon Web Services, Inc.)


2. S3의 개념: 버킷(Bucket)과 객체(Object)

AWS S3에는 버킷(Bucket)객체(Object)라는 기본 단위가 있습니다.

  • 객체(Object): 실제 저장되는 데이터입니다. 파일 본문뿐 아니라 메타데이터도 함께 포함됩니다.
  • 버킷(Bucket): 객체를 담는 컨테이너입니다.

AWS 공식 문서에서도 S3는 객체를 버킷 안에 저장하는 구조라고 설명합니다.
또한 각 객체는 고유한 키(key) 로 식별됩니다. (AWS Documentation)

조금 헷갈릴 수 있는 부분이 있는데,
버킷은 흔히 폴더처럼 비유되지만 정확히는 “객체를 담는 컨테이너”에 가깝습니다.
S3 콘솔에서 보이는 폴더 구조도 실제 파일 시스템 디렉터리라기보다
객체 키(prefix)로 표현되는 경우가 많습니다. (Amazon Web Services, Inc.)

예를 들어 User라는 버킷에 profile.png라는 객체를 저장하면,
해당 객체는 버킷 이름, 리전, 객체 키를 바탕으로 접근 경로를 가지게 됩니다.
다만 실제로 URL로 접근 가능한지는 퍼블릭 접근 권한 설정 또는 Presigned URL 발급 여부에 따라 달라집니다.
즉, S3에 저장되었다고 해서 무조건 누구나 바로 접근 가능한 공개 URL이 생기는 것은 아닙니다. (Amazon Web Services, Inc.)


3. S3 업로드 방식

S3에 파일을 업로드하는 방식은 여러 가지가 있지만,
실무에서 자주 비교하게 되는 방식은 크게 다음과 같습니다.


1. 스트림 업로드 (Stream Upload)

스트림 업로드는 파일 데이터를 흐름(stream) 형태로 읽어서 업로드하는 방식입니다.

이 방식은 파일 전체를 한 번에 메모리에 올리지 않고 처리할 수 있기 때문에
상대적으로 메모리 부담을 줄이는 데 유리합니다.
특히 큰 파일을 서버에서 직접 받아 S3로 넘기는 상황에서 자주 고려할 수 있습니다.

다만 한 번의 요청으로 하나의 파일을 처리하는 흐름이 일반적이며,
업로드가 길어질수록 사용자 입장에서는 대기 시간이 길게 느껴질 수 있습니다.


2. MultipartFile 업로드

MultipartFile은 Spring에서 multipart/form-data 요청을 다루기 쉽게 만든 객체입니다.

즉, 사용자가 폼을 통해 이미지 파일과 텍스트 데이터를 함께 전송할 때
Spring에서는 이를 MultipartFile 형태로 받아 쉽게 처리할 수 있습니다.

이 방식은 다음과 같은 경우에 특히 편리합니다.

  • 파일과 함께 다른 데이터도 같이 보내야 할 때
  • 여러 개의 작은 파일을 한 번에 업로드할 때
  • Spring MVC에서 빠르게 업로드 기능을 구현하고 싶을 때

다만 요청을 처리하는 과정에서 메모리나 임시 디스크를 사용할 수 있기 때문에,
동시에 많은 업로드 요청이 몰리면 서버 자원 사용량을 주의해서 봐야 합니다.


Stream vs MultipartFile

두 방식의 차이를 간단히 정리하면 다음과 같습니다.

Stream 방식
파일 데이터를 흐름으로 처리하므로 큰 파일 업로드에서 메모리 부담을 줄이기 좋습니다.
대신 사용자 경험 측면에서는 업로드 시간이 길어질 수 있고,
파일 외의 다른 데이터를 한 번에 함께 다루는 데는 불편할 수 있습니다.

MultipartFile 방식
Spring에서 다루기 편하고, 파일과 다른 폼 데이터를 함께 처리하기 좋습니다.
여러 개의 작은 파일을 전송하는 상황에도 잘 어울립니다.
반면 업로드 요청이 많아질수록 서버 자원 관리에 주의가 필요합니다.

정리하면 다음처럼 이해하면 편합니다.

  • 큰 파일을 효율적으로 처리하고 싶을 때 → Stream 방식
  • 파일과 폼 데이터를 함께 다루거나 여러 개의 작은 파일을 업로드할 때 → MultipartFile 방식

3. AWS 멀티파트 업로드 (AWS Multipart Upload)

AWS의 Multipart Upload는 큰 파일을 S3에 더 효율적으로 업로드하기 위한 방식입니다.

이 방식은 하나의 큰 파일을 여러 개의 part로 나누어 업로드합니다.
각 part는 독립적으로 업로드할 수 있고, 실패한 part만 다시 업로드할 수 있습니다.
AWS는 100MB 이상 객체의 경우 단일 업로드 대신 멀티파트 업로드 사용을 권장하고 있습니다.
또한 각 part는 보통 5MiB~5GiB 범위여야 하며, 마지막 part는 최소 크기 제한의 예외가 될 수 있습니다. (AWS Documentation)

즉, 멀티파트 업로드는 대용량 파일 업로드에 더 안정적이고 유리한 방식입니다.


AWS 멀티파트 업로드 4단계 프로세스

1. Multipart 업로드 시작

먼저 업로드를 시작하겠다는 요청을 보냅니다.
그러면 S3는 해당 업로드를 식별할 수 있는 UploadId를 반환합니다. (AWS Documentation)

2. 각 파트 업로드 준비

이후 각 part를 업로드할 준비를 합니다.
실무에서는 서버가 part별 Presigned URL을 만들어 클라이언트에 전달하는 구조를 자주 사용합니다.
Presigned URL은 일정 시간 동안 인증 없이도 특정 객체나 업로드 작업에 접근할 수 있도록 해주는 URL입니다. (AWS Documentation)

3. part 업로드

클라이언트는 각 part를 S3에 직접 업로드합니다.
이 part들은 독립적으로, 그리고 순서와 상관없이 업로드할 수 있습니다.
업로드에 실패한 경우에는 해당 part만 다시 보내면 됩니다. (AWS Documentation)

4. Multipart 업로드 완료

모든 part 업로드가 끝나면,
클라이언트 또는 서버는 part 번호와 ETag 정보를 모아 완료 요청을 보냅니다.
그러면 S3가 이 part들을 결합해 하나의 최종 객체로 만듭니다.
S3는 업로드 완료 시 part 번호 순서대로 객체를 조합합니다. (AWS Documentation)


4. S3 요금

S3는 기본적으로 사용한 만큼 비용을 내는 구조입니다.
버킷을 만드는 것 자체에는 비용이 들지 않지만,
버킷 안에 저장한 객체의 용량, 요청 수, 데이터 전송량 등에 따라 과금될 수 있습니다. (AWS Documentation)

여기서 중요한 점은 프리 티어 정책이 계정 생성 시점에 따라 달라질 수 있다는 것입니다.

기존 S3 안내 페이지에는
다음과 같은 12개월 무료 사용량이 표시되어 있습니다.

  • S3 Standard 5GB
  • GET 요청 20,000건
  • PUT, COPY, POST, LIST 요청 2,000건
  • 월 100GB 데이터 전송 아웃 (Amazon Web Services, Inc.)

하지만 AWS는 2025년 7월 15일 이후 신규 고객 대상 Free Tier 정책을 업데이트해, 최대 200달러 크레딧 중심 구조를 도입했다고 안내하고 있습니다.
또한 AWS Billing 문서에서도 2025년 7월 15일 이전 생성 계정과 이후 생성 계정을 구분해 설명하고 있습니다. (AWS Documentation)

따라서 지금 글에서는 프리 티어를 이렇게 정리하는 편이 더 안전합니다.

S3 프리 티어 혜택은 AWS 계정 생성 시점에 따라 달라질 수 있으므로,
실제 사용 전에는 AWS Free Tier 및 S3 Pricing 페이지를 반드시 확인하는 것이 좋습니다.

또한 사용하지 않는 객체를 계속 저장해두면 비용이 발생할 수 있으므로,
테스트 용도로 올린 파일은 주기적으로 정리하는 습관이 필요합니다.
AWS도 객체와 버킷을 더 이상 사용하지 않을 때 삭제해 추가 비용 발생을 막는 것을 권장합니다. (AWS Documentation)


📌 결론

이번 포스트에서는 사용자 프로필 이미지처럼 파일을 저장해야 할 때
S3를 어떤 방식으로 활용할 수 있는지 정리해보았습니다.

정리해보면,

  • S3는 객체 스토리지 서비스이며
  • 버킷 안에 객체를 저장하는 구조를 가지고 있고
  • 업로드 방식은 상황에 따라 Stream, MultipartFile, AWS Multipart Upload로 나누어 생각할 수 있습니다.

특히 작은 파일을 간단히 처리할 때는 MultipartFile이 편리하고,
큰 파일을 안정적으로 업로드해야 할 때는 AWS Multipart Upload가 더 적합합니다.

즉, 업로드 방식은 “무조건 하나가 더 좋다”기보다
파일 크기, 서버 자원, 사용자 경험, 업로드 안정성을 함께 고려해 선택해야 합니다.


참고

  • AWS S3 공식 문서
  • AWS S3 Pricing
  • AWS Free Tier
profile
달을 향해 쏴라, 빗나가도 별이 될 테니 👊

0개의 댓글