Amazon S3 저장 비용과 이미지 CDN 트래픽 최적화
S3 Intelligent-Tiering과 AVIF·MP4 변환으로 저장·전송 비용을 줄였다.
인프랩은 강의 영상 원본과 여러 해상도 인코딩본, 오디오 정규화 결과물, 썸네일 스프라이트, CDN 액세스 로그까지 S3에 대량 저장하면서 보관 비용이 계속 증가하는 문제를 겪었다. 단순한 Lifecycle rule만으로는 객체 접근 패턴을 세밀하게 반영하기 어렵고, 스토리지 클래스 전환 비용과 복구 비용도 부담이 컸다.
해결책으로 S3 Intelligent-Tiering을 도입했다. 업로드 즉시 클래스 전환이 가능하고, 접근 패턴을 알기 어려우며, 128KB 초과 객체가 많고, CloudFront 같은 캐싱 계층이 있는 버킷에 특히 잘 맞았다. 기본적으로 30일 무접근 시 IA, 90일 무접근 시 AIA로 이동하며, 관리 비용은 1,000개 객체당 $0.0025 수준이다.
도입 비용도 먼저 계산했다. 기존 객체를 Lifecycle로 전환할 때는 1,000개당 $0.01의 전환 비용이 들기 때문에, 객체 수가 많을수록 사전 산정이 중요했다. 신규 업로드는 put_object(..., StorageClass="INTELLIGENT_TIERING")로 처리했고, 원본 영상처럼 아카이브 성격이 강한 버킷은 CopyObject로 일괄 전환해 전환 요청 비용을 줄였다.
적용 방식은 버킷 특성에 따라 달랐다.
- 신규 객체: PutObject 시 Intelligent-Tiering 지정
- 아카이브 버킷: CopyObject로 일괄 전환
- 인코딩 결과물 버킷: 파일 크기 기준으로 Lifecycle rule을 점진 적용
전환 후 3~4개월이 지나면서 자주 접근되지 않는 객체의 비용이 줄어들었고, 전체 S3 비용은 38% 절감됐다. 객체 수와 크기를 사전에 파악하기 위해 S3 Inventory와 Athena 쿼리도 활용했고, 128KB 초과 객체 수와 예상 전환 비용을 먼저 산정한 뒤 적용했다.
이미지 CDN 트래픽 최적화에서는 CloudFront + Lambda@Edge 기반 리사이저를 사용했다. 요청 시점에 필요한 크기와 포맷으로 변환하고, 캐시 미스 때만 실행되도록 해 원본 이미지를 여러 크기로 미리 저장하지 않아도 되게 만들었다.
포맷 측면에서는 AVIF를 추가해 트래픽을 더 줄였다. 썸네일 변환 테스트에서 원본 JPG 100KB가 WebP는 68KB, AVIF는 55KB로 줄어들었다. Sharp가 AVIF를 지원하므로 허용 포맷에 avif를 추가하는 정도의 작업으로 적용할 수 있었다.
브라우저 호환성을 위해서는 <picture> 태그로 폴백을 구성했다. AVIF를 지원하면 AVIF를, 아니면 WebP를, 둘 다 아니면 원본 JPG를 내려주는 방식이다. 다만 AVIF는 WebP보다 인코딩이 느리고, 하드웨어 디코딩 지원도 제한적이라 프론트엔드에서의 폴백 설계가 중요했다.
애니메이션 GIF는 Lambda@Edge에서 실시간 변환하기엔 제약이 컸다. Sharp는 animated AVIF를 지원하지 않고, Lambda@Edge는 패키지 크기 50MB, Origin Response 응답 크기 1MB, 실행 시간 30초 제한이 있어 대용량 GIF 처리에 적합하지 않았다.
그래서 GIF는 일반 Lambda와 FFmpeg를 이용해 업로드 시점에 MP4(H.264) 로 미리 변환했다. 흐름은 S3 업로드 → ObjectCreated 이벤트 → Lambda 실행 → GIF 다운로드 → MP4 변환 → S3 저장 순서이며, 프론트엔드에서는 <video> 태그로 재생했다. 이 방식은 초기 업로드 지연은 있지만, 장기적으로 CDN 트래픽을 줄이고 사용자에게 더 가벼운 미디어를 제공할 수 있었다.
이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.
요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.