Fullmoon System

S3 비용 줄이기: 삭제 후 남은 버전·멀티파트 업로드 확인

AI Editter

S3에서 파일을 지웠는데 저장 비용이 줄지 않는다면 객체 목록에 보이지 않는 데이터를 확인해야 합니다. 버전 관리가 켜진 버킷에는 이전 버전이 남을 수 있고, 끝나지 않은 멀티파트 업로드의 조각도 저장 공간을 차지합니다. 현재 파일 수, 전체 버전 용량, 업로드 조각, 요청·전송 비용을 나눠 보는 것이 S3 비용 점검의 출발점입니다.

이 글은 일반 S3 버킷의 저장 비용 점검을 다룹니다. 리전별 단가와 스토리지 클래스의 최소 보관 기간은 다르므로 특정 원화 금액을 고정하지 않습니다. 삭제 정책은 복구 가능 기간을 바꾸는 작업이므로 보존 의무와 백업 요구를 먼저 정하세요.

1. 청구서에서 저장 비용인지부터 확인한다

Billing의 Cost Explorer에서 서비스를 S3로 한정하고 리전과 Usage type을 나눠 봅니다. Storage 계열이 늘었는지, Requests나 Data Transfer가 늘었는지에 따라 다음 작업이 달라집니다. 파일을 줄였는데 다운로드가 급증했다면 저장 공간 정리만으로 청구 증가를 설명할 수 없습니다.

관찰 결과 다음 점검 피해야 할 오판
현재 객체는 적고 전체 용량은 큼 비현재 버전·미완료 업로드 콘솔 파일 수가 전체 저장량이라고 판단
스토리지 클래스 전환 후 비용 증가 전환 요청, 최소 보관·최소 객체 크기 조건 GB 단가만 비교
요청 비용 증가 앱의 LIST·GET 반복, 재시도 버전 삭제로 해결하려 함
전송 비용 증가 다운로드·리전 간 전송 경로 저장 용량과 같은 항목으로 취급

여러 버킷이 있다면 S3 Storage Lens에서 버킷별 현재·비현재 버전과 미완료 업로드 관련 지표를 비교합니다. 집계형 지표는 실시간 파일 목록과 시점이 다를 수 있습니다. AWS의 S3 비용 점검 안내와 Lifecycle 비용·동작 문제 해결 문서가 항목을 구분하는 데 도움이 됩니다.

S3 삭제 마커 아래의 이전 버전과 미완료 멀티파트 조각을 확인하고 Lifecycle을 적용하는 개념도
직접 제작한 설명 도식이며 실제 AWS 콘솔 화면이 아닙니다. ①~③은 점검 순서이며 콘솔 버튼 번호가 아닙니다. 공식 참고 문서 · 그림을 누르면 크게 볼 수 있습니다.
  1. ① 이전 버전: 버킷의 Objects에서 Show versions를 켜고 같은 키의 과거 버전을 봅니다. 삭제 마커가 있다는 사실만으로 데이터가 모두 지워진 것은 아닙니다.
  2. ② 미완료 업로드: 아래의 list-multipart-uploads로 남은 업로드를 찾고, 필요한 경우 list-parts나 Storage Lens 지표로 범위를 확인합니다. 현재 객체 목록만으로 판단하지 않습니다.
  3. ③ 정책 적용: 남은 데이터의 종류와 보존 기간을 확인한 뒤 Management의 Lifecycle rules에서 대상 prefix를 한정합니다. 이전 버전 삭제와 미완료 업로드 정리는 서로 다른 동작을 선택해야 합니다.

2. 버전 관리 버킷은 ‘삭제’와 ‘영구 삭제’가 다르다

S3 콘솔에서 버킷 → Objects → Show versions를 켭니다. 같은 키에 여러 버전이 있는지, delete marker 아래에 과거 데이터가 남는지 확인하세요. 버전 ID 없이 일반 삭제한 객체는 삭제 마커가 현재 버전이 되고 원래 데이터가 비현재 버전으로 남을 수 있습니다. 버전 삭제 방식에 따른 차이입니다.

예를 들어 1GB 백업 파일을 같은 키에 30번 덮어썼다고 가정하면, 현재 목록에는 파일 하나만 보여도 과거 버전들이 별도 공간을 차지할 수 있습니다. 이 예시는 구조를 설명하기 위한 가정이며 실제 청구액 계산은 아닙니다. “최신 파일은 유지하고 과거 버전은 30일 보관”처럼 요구사항을 분리해야 합니다.

aws s3api get-bucket-versioning --bucket YOUR_BUCKET
aws s3api list-object-versions --bucket YOUR_BUCKET \
  --prefix backups/ --max-items 20
aws s3api list-multipart-uploads --bucket YOUR_BUCKET \
  --prefix backups/ --max-items 20

위 명령은 읽기 전용이며 승인된 AWS 프로필로 실행합니다. 20건 제한은 샘플 확인용이므로 합계를 내거나 “더는 없다”고 판단하면 안 됩니다. 큰 버킷은 페이지네이션을 끝까지 처리하거나 Inventory·Storage Lens를 사용합니다. 키 이름에도 고객 정보가 포함될 수 있어 결과 전체를 공개하지 않습니다.

3. 미완료 멀티파트 업로드는 별도로 정리한다

대용량 업로드가 중단되면 완성된 객체가 없어도 업로드된 part가 남을 수 있습니다. list-multipart-uploads는 업로드 작업을 찾는 명령이며 part 전체 크기를 보여 주는 목록은 아닙니다. 특정 작업은 list-parts로 확인하거나 집계 지표를 사용하세요.

버킷 → Management → Lifecycle rules → Create lifecycle rule에서 대상 prefix를 한정하고 Delete incomplete multipart uploads의 기간을 정할 수 있습니다. 실제로 오래 걸리는 정상 업로드보다 넉넉한 기간을 선택해야 합니다. 예를 들어 7일은 정책 예시일 뿐 모든 서비스의 권장값이 아닙니다.

일반 객체 만료 규칙은 미완료 업로드를 대신 지우지 않습니다. AbortIncompleteMultipartUpload 동작이 따로 필요하며 객체 태그 필터와의 제약도 있습니다. Lifecycle 요소 설명을 확인해 별도 규칙으로 관리하세요.

4. 과거 버전의 보존 정책을 좁은 범위부터 적용한다

비현재 버전을 정리하려면 Permanently delete noncurrent versions of objects를 검토합니다. 현재 버전 만료와 혼동하면 서비스가 사용하는 최신 파일에 삭제 마커가 붙을 수 있습니다. 먼저 테스트용 prefix의 대표 파일을 골라 버전 생성 시각, 비현재 전환 시각, 복원 가능 여부를 기록하세요.

보존 일수와 보존할 새 버전 수를 함께 설정하는 경우 두 조건이 모두 충족되어야 삭제되는 규칙이 있습니다. 단순히 “30일이 지났으니 모두 지워진다”고 예상하지 않습니다. Object Lock이나 legal hold가 있는 버전은 보호 조건도 확인해야 합니다. 실제 옵션은 AWS Lifecycle 예제와 대조합니다.

정리 후에는 당일 총액 대신 다음 기간의 사용량을 본다

이미 발생한 사용량이 객체 삭제로 소급 취소되지는 않습니다. Lifecycle 적용은 비동기이고 비용·용량 지표에도 집계 지연이 있습니다. 규칙 범위와 대상 버전을 확인한 뒤 다음 집계에서 비현재 버전 용량과 미완료 업로드 용량의 추세를 비교하세요. 필요한 최신 파일을 실제 애플리케이션에서 읽을 수 있고, 합의한 복구 기간의 버전이 남는지도 함께 검사합니다.

예산 알림은 삭제 정책을 대신하지 않습니다. 비용 증가를 빨리 발견하는 알림과 데이터 보존 정책을 함께 운영해야 같은 문제가 반복되지 않습니다.

계정 전체의 지출 알림을 함께 설정하려면 AWS 예산 알림과 과금 자원 점검을 참고하세요.