← 기술 블로그

S3 스토리지 비용 최적화 실전: 과금 요소 분석부터 7가지 실행 가능한 방안까지

많은 팀이 S3 청구서를 볼 때 “몇 TB를 저장했는가”에만 집중하지만, 실제 S3 비용은 보통 네 가지 비용 요소가 누적되어 발생합니다: 스토리지 용량, 요청 횟수, 데이터 전송, 관리 기능. 따라서 최적화 역시 단순히 모든 bucket을 더 저렴한 스토리지 클래스로 이전하는 것이 아니라, 이 네 가지 차원에서 나누어 접근해야 합니다.

아래 가격은 us-east-1을 기준으로 한 예시이며, 실제 비용은 AWS 리전별 가격을 기준으로 합니다: S3 Standard 최초 50TB는 약 $0.023/GB-month이며, Standard-IA는 약 $0.0125/GB-month, Glacier Instant Retrieval은 약 $0.004/GB-month, Glacier Deep Archive는 약 $0.00099/GB-month입니다. Deep Archive가 훨씬 저렴해 보이지만, 최소 저장 기간, 복원 시간 및 복원 비용이 있으므로 무조건 이전해서는 안 됩니다.

1. 먼저 청구 비용의 발생원 파악하기

먼저 Cost Explorer에서 Usage type별로 세분화하여 분석하는 것을 권장합니다:

  • TimedStorage-ByteHrs: 객체 스토리지 용량.
  • Requests-Tier1/Tier2: PUT, LIST, GET 등의 요청.
  • DataTransfer-Out-Bytes: 퍼블릭 인터넷 혹은 리전 간 데이터 전송.
  • Monitoring-Automation, Inventory, StorageLens: 관리 및 분석 기능.

흔히 하는 오해 중 하나는 스토리지 비용은 높지 않지만 LIST/GET 요청이 매우 많거나, 프라이빗 서브넷에서 S3에 액세스할 때 NAT Gateway를 거쳐 네트워크 청구 비용이 급증하는 경우입니다. S3 최적화는 단순히 bucket size만 보고 판단해서는 안 됩니다.

2. Intelligent-Tiering 및 수명 주기 규칙

객체 액세스 패턴이 불규칙하다면 S3 Intelligent-Tiering은 리스크가 적은 시작점입니다. Frequent, Infrequent, Archive Instant 등의 계층 간에 객체를 자동으로 이동시키며, 자동 계층 간 이동 시에는 복원 비용이 발생하지 않습니다. 하지만 모니터링 및 자동화 비용이 부과되며, 일반적인 가격은 $0.0025/1,000 objects-month입니다. 만약 객체의 크기가 매우 작고 개수가 방대하다면, 이 관리 비용이 더 비효율적일 수 있습니다.

수명 주기 규칙은 로그, 백업, 학습 데이터와 같이 액세스 패턴이 명확한 데이터에 적합합니다:

{
  "Rules": [
    {
      "ID": "logs-to-glacier",
      "Status": "Enabled",
      "Filter": { "Prefix": "logs/" },
      "Transitions": [
        { "Days": 30, "StorageClass": "STANDARD_IA" },
        { "Days": 90, "StorageClass": "GLACIER_IR" },
        { "Days": 180, "StorageClass": "DEEP_ARCHIVE" }
      ],
      "Expiration": { "Days": 730 }
    }
  ]
}

최소 저장 기간에 유의해야 합니다: Standard-IA는 보통 30일, Glacier Instant Retrieval / Flexible Retrieval은 보통 90일, Deep Archive는 보통 180일입니다. 수명이 짧은 객체는 너무 이른 시점에 콜드 스토리지로 전환하는 것이 적절하지 않습니다.

3. Glacier IR 및 Deep Archive: 정말로 “콜드”한 데이터에만 적용하기

Glacier Instant Retrieval은 “액세스 빈도는 낮지만 밀리초 단위의 빠른 읽기가 필요한” 아카이브(예: 컴플라이언스 쿼리, 기록 보고서)에 적합합니다. Deep Archive는 거의 조회할 일이 없으며 복원까지 수 시간을 대기해도 무방한 데이터(예: 수년 동안 보관하는 백업)에 적합합니다.

판단 기준은 매우 직관적일 수 있습니다: 객체를 6개월 이내에 읽을 확률이 극히 낮다면 Deep Archive 도입을 검토할 가치가 있습니다. 만약 현업 부서에서 복원 대기 시간을 수용할 수 없다면, 단순히 청구 비용을 낮춰 보이기 위해 무리하게 이전해서는 안 됩니다.

4. 이전 버전 및 미완료 Multipart Upload 정리

Versioning을 활성화하면 객체를 삭제해도 delete marker만 생성될 뿐, 이전 버전은 여전히 과금됩니다. 많은 bucket의 “유령 비용”이 바로 이 이전 버전에서 발생합니다.

우선 버전을 확인해볼 수 있습니다:

aws s3api list-object-versions --bucket my-bucket --prefix app/

그다음 수명 주기를 사용하여 현재 버전이 아닌 버전을 정리합니다:

{
  "Rules": [
    {
      "ID": "expire-old-versions",
      "Status": "Enabled",
      "Filter": {},
      "NoncurrentVersionExpiration": { "NoncurrentDays": 30 },
      "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
    }
  ]
}

AbortIncompleteMultipartUpload는 매우 쉽게 간과되는 부분입니다. 대용량 파일 업로드에 실패한 후, 업로드 분할 조각(part)들이 S3에 장기간 남아 계속해서 비용을 발생시킬 수 있습니다.

5. 요청 최적화: LIST는 생각보다 비쌉니다

S3 Standard에서 PUT/COPY/POST/LIST와 같은 요청은 일반적으로 약 $0.005/1,000 requests이며, GET은 약 $0.0004/1,000 requests입니다. 단가는 낮아 보이지만 객체 수가 수억 개에 달할 때, 전체를 훑는 LIST 작업은 매우 비쌀 뿐만 아니라 시스템 속도도 저하시킵니다.

실무적인 제안은 다음과 같습니다:

  • ListObjectsV2를 데이터베이스 쿼리처럼 사용하는 것을 피하세요.
  • 객체 key 설계 시 날짜, 테넌트, 비즈니스 접두사(prefix)를 포함시켜 무의미한 스캔을 줄이세요.
  • 전체 LIST를 수행하는 대신 S3 Inventory를 활용하세요.
  • 트래픽이 몰리는 작은 객체들은 병합하거나 캐싱하여 GET 요청 폭증을 방지하세요.

6. VPC Endpoint를 활용해 NAT Gateway 경유 피하기

프라이빗 서브넷에 있는 EC2, ECS, Lambda에서 S3에 액세스할 때 라우팅이 NAT Gateway를 거치게 되면 NAT 데이터 처리 비용이 발생합니다. us-east-1 기준 일반적인 NAT Gateway 가격은 시간당 약 $0.045/hour에 처리된 데이터 GB당 $0.045/GB processed가 추가되므로, 월 1TB의 데이터만 전송해도 NAT 처리 비용만 약 $45가 청구됩니다.

S3 및 DynamoDB에 액세스할 때는 Gateway VPC Endpoint를 우선적으로 구성하세요:

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxxx \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-xxxx \
  --vpc-endpoint-type Gateway

Gateway Endpoint 자체는 보통 시간당 요금이 부과되지 않으며, NAT를 경유하는 트래픽도 줄일 수 있습니다. 설정을 변경한 후에는 route table을 확인하여 S3 prefix list가 endpoint를 가리키고 있는지 검증해야 합니다.

7. 압축: 애플리케이션 레벨 압축 vs 투명 게이트웨이

압축은 가장 직접적인 용량 최적화 방안이지만 데이터 유형에 따라 다릅니다. Parquet, ORC, gzip 처리된 로그, 이미지, 비디오 등은 이미 압축되어 있는 경우가 많아 비용 절감 효과가 제한적입니다. 반면 JSON, CSV, 일반 텍스트 로그, 압축되지 않은 객체, 일부 백업 파일 등은 큰 효과를 기대할 수 있습니다.

애플리케이션 측에서 압축을 수행하는 방법은 아키텍처가 단순하고 추가 게이트웨이가 필요 없다는 장점이 있지만, 코드를 수정해야 하고 호환성 문제를 처리해야 하며 기존의 레거시 데이터를 마이그레이션해야 한다는 단점이 있습니다. 또 다른 방식은 투명 압축 게이트웨이(transparent compression gateway)를 사용하는 것입니다. 애플리케이션은 기존 S3 API를 그대로 유지한 채 클라이언트의 대상을 게이트웨이로 지정하고, 게이트웨이가 압축을 담당하여 S3에 쓰는 방식입니다.

S4(Squished S3)가 바로 후자에 해당합니다. 이는 NVIDIA nvCOMP GPU codec이 포함된 EC2 AMI로, g4dn/g5/g6 등의 GPU 인스턴스에서 실행됩니다. S3 클라이언트가 이 투명 게이트웨이를 바라보도록 설정하면 압축이 가능한 데이터에 대해 일반적으로 50%에서 80%까지 S3 저장 용량을 줄일 수 있으며, 애플리케이션 코드를 전혀 수정할 필요가 없습니다. 다만 모든 시나리오에 적합한 것은 아닙니다. 이미 데이터가 압축되어 있거나, 객체의 크기가 매우 작고, 요청 수는 극도로 많지만 전체 용량이 크지 않은 경우에는 비용 절감 효과가 미미할 수 있습니다. 도입을 검토하기 좋은 시나리오는 S3에 텍스트 및 반정형 데이터가 대량으로 적재되어 용량 비용이 주된 문제이며, 동시에 애플리케이션 코드를 수정하고 싶지 않은 경우입니다.

먼저 S4 비용 계산기를 통해 대략적인 비용을 산출해볼 수 있습니다. 자체 청구서 CSV 파일을 업로드할 필요 없이 샘플 데이터를 활용해 테스트해볼 수도 있습니다.

마지막으로: 먼저 측정하고, 그 뒤에 전략을 변경하세요

권장하는 적용 단계는 다음과 같습니다:

  1. Cost Explorer를 활용해 S3의 핵심 usage type을 식별합니다.
  2. S3 Storage Lens를 통해 bucket, prefix, 버전, 객체 크기 분포를 확인합니다.
  3. 먼저 이전 버전 및 미완료 multipart를 정리합니다.
  4. 그 다음 수명 주기 규칙, Endpoint, 요청 최적화를 적용합니다.
  5. 마지막으로 압축 도입 또는 대체 아키텍처를 검토합니다.

S3 비용 절감은 단순히 “모든 데이터를 콜드로 전환”하는 것처럼 간단하지 않습니다. 진정으로 효과적인 방법은 데이터 액세스 패턴, 객체 크기, 요청 경로 및 보관 주기를 종합적으로 분석하여 최적화하는 것입니다.

알림: 본문 작성자는 abyo software(AWS Marketplace의 비용 최적화 제품 S4의 개발사) 소속입니다.