비용을 줄이는 관점에서 S3의 버킷의 버전관리는 비용을 증가시키는 요소이다. 특히 객체를 빈번하게 변경하고 삭제할 경우에 그 비용은 점점 커진다. 데이터가 실제로 삭제되는 것이 아니기 때문이다.
버전관리를 한번 활성화하면 비활성화할 수 없다. 버킷을 빈번하게 사용하고 있어서 버킷 자체를 이동시킬 수 없다면 어떻게 해야 할까? 그 방법에 대해 정리하였다.
버전 관리(Versioning)는 데이터를 실수로 삭제하거나 덮어쓰는 것을 방지하기 위한 기능이다. 버킷에서 버전 관리를 활성화하면, 해당 버킷의 모든 객체는 버전 ID를 가지며, 객체가 삭제되거나 덮어쓰기되더라도 원본 객체가 보존된다. 다만 버전과리를 활성화한 채로 빈번하게 객체의 변경을 하고 삭제를 할 경우 그 비용이 점점 불어날 수밖에 없는 구조를 가지고 있다. 따라서 비용절감 차원에서 버전관리를 활성화한 버킷을 비활성화하고자 할 경우에 어떻게 해야 할지 고민이 필요하다.
버전관리를 비활성화함으로써 일 비용 $5, 월 $150을 절감할 수 있었다.
버전관리의 의미와 비활성화하는 방법에 대해 자세히 알아보자
버전관리의 동작 예시는 아래와 같다
버전관리를 활용하게 되면 실수로 덮어쓴 파일이나 삭제한 것도 이전 버전으로 롤백 및 복원이 가능해진다.
당연히 덮어쓰거나 삭제하더라도 이전 버전도 스토리지에 남아 있기 때문에 추가 비용이 발생할 수 있다. 비용 최적화를 위해 수시로 이전 버전 정리가 필요할 수 있다.
비용 관점에서 정리해보면, 하나의 파일에 대해 덮어쓰기와 삭제를 수행했다고 할 때, 파일 2개(v1, v2)의 비용이 아래와 같이 여전히 과금된다고 보면 된다.
Q. 비용절감을 위해 버전관리를 지울 수 있을까?
버전관리를 하게 되면 비용이 증가할 수 있다. 따라서 이전 버전을 삭제하는 방법에 대해 고민해야 하는데 이는 S3 Lifecycle Rule을 설정하여 해결할 수 있다. 단, 이전 버전과 삭제 마커는 아래와 같이 각각 개별로 설정해야 한다. 이는 S3 콘솔에서 관리가 가능하다.
Q. 버킷의 버전관리를 활성화한 뒤 비활성화할 수 있는가?
버전 관리(Versioning)는 한 번 활성화하면 완전히 비활성화하는 것은 불가능하다. AWS의 설계상 데이터 무결성과 보호를 위한 기능으로, 한 번 켜면 비가역적으로 되돌릴 수 없다. 다만 일시 중지를 통해 새로운 버전의 객체 생성을 중단할 수 있다.
버전 관리가 일시 중지되면, 이후 업로드되는 객체는 버전 ID 없이 저장된다. 그러나 이전에 저장된 버전 정보는 계속 유지된다. 당연히 삭제도 되지 않는다. 일시 중지된 이후 저장되는 객체는 더 이상 버전 관리 대상이 아니다. 버전 ID가 없고, 새 버전으로 관리되지 않으며 이전 버전이 저장되지 않는다. 즉시 삭제도 가능하다. 따라서 비활성화된 상태와 똑같은 프로세스라고 볼 수 있다.
Q. 그래도 비활성화를 하고 싶다면 어떻게 하는가?
사용하지 않는 객체가 해당 버킷에 많이 있거나, 비용을 줄이기 위해 비활성화를 하고 싶을 수 있다. 버전 관리 기능을 완전히 제거하고 싶다면 다음 방법들이 있다.
방법 1: 새 버킷을 만들어서 데이터 복사
버전 관리가 꺼져 있는 새로운 버킷을 생성
기존 버킷의 최신 객체만 복사 (예: aws s3 cp --recursive)
기존 버킷 삭제 또는 아카이브
방법 2: 라이프사이클 정책 적용 (추천)
일정 기간 이후 이전 버전을 삭제한다.
방법 3: 버전 삭제 스크립트 활용
스크립트를 작성해 바로 객체들의 이전 버전을 삭제한다.
예: s3-delete-versions 스크립트 또는 AWS CLI 루프
버전관리 비활성화 상태, 버전관리 활성화 상태, 버전관리 일시중지 상태를 비교하면 아래와 같다.
Q. 버전 관리를 하는 상황에서 Standard class에서 Intelligent-Tiering class로 변경하는 것은 문제 없을까?
문제 없다. 이전 버전 및 삭제마커가 달린 객체 모두 Intelligent-Tiering으로 전환된다. Intelligent-Tiering의 장점인 자동 저비용 객체 전환이 이전버전과 삭제버전 모두 적용된다. 즉, 이전버전과 삭제버전은 자주 접근을 하지 않을 것이므로 Infrequent Access로 전환될 것이다.
Q. 버전관리 대상을 완전히 삭제하려면 어떻게 해야 할까?
1) 전체 버킷을 대상으로 할 경우
전체 버킷을 대상으로 할 경우 콘솔에서 라이프사이클을 생성해 쉽게 적용이 가능하다. 여기서 객체의 이전 버전 전환에 대한 라이프사이클을 고려하기보다 객체의 이전 버전 영구 삭제를 관리하는 것이 좋다.
수명주기를 생성하는 콘솔에서 ‘객체의 이전 버전 영구 삭제’를 enable
아래 세부항목에서 객체가 최신이 아닌 상태로 전환된 후 경과 일수에 숫자 기입
만료된 객체 삭제 마커 또는 완료되지 않은 멀티파트 업로드 삭제 enable
아래 세부항목에서 만료된 객체 삭제 마커 삭제 enable
2) 객체별, 폴더별로 다르게 접근할 경우
버전 관리가 활성화된 객체를 “완전히 삭제” 하려면 특정 Version ID를 지정해야 한다. 일반적인 DELETE 요청은 삭제 마커(Delete Marker)를 생성하고 객체를 그대로 유지한다.
또한 라이프사이클을 통해 자동 삭제를 할 수 있다. 아래와 같이 NoncurrentVersionExpiration을 명시하면 이전 버전은 삭제된다. 그러나 이미 삭제 요청을 해서 delete marker가 생성된 객체라면 아래의 ExpiredObjectDeleteMarker 정책도 추가시켜야 한다. 모든 버전의 객체가 없을 때 남아있는 마커를 제거할 수 있고 이를 통해 완전히 삭제가 가능하다. 쉽게 설명하면 delete marker가 있는 객체도 버전 지정을 통해 삭제할 수 있다. 단 delete marker 자체는 삭제 되지 않으므로 ExpiredObjectDeleteMarker 정책으로 삭제하는 것이다. delete marker도 매우 작지만 용량을 차지하는 삭제 이력이다. 따라서 정책을 통해 완전히 삭제를 하는 것이 옳다.
위를 감안하면, 아래와 같은 스크립트를 통해 버전관리 중인 이미지의 모든 버전과 delete marker를 완전히 삭제할 수 있다. 단 삭제하고자 하는 키 값은 코드 내에서 명확하게 명시되어야 한다.
버전관리로 되어 있는 버킷의 모든 객체를 비활성화 모드로 전환하고자 할 때 아래와 같이 진행하면 된다
버전관리 활성화를 일시중지시킨다. 앞으로 등록되는 객체는 비활성화 상태가 될 것이다.
버킷의 라이프사이클에서 객체의 이전 버전 영구 삭제, 만료된 객체 삭제 마커 또는 완료되지 않은 멀티파트 업로드 삭제 2개를 활성화한다. 이미 등록된 객체를 비활성화 상태로 변경하는 것이며 이 때 스토리지 클래스 간에 객체의 이전 버전 전환은 설정할 필요 없음
이로써 S3 저장 비용으로 이미 많은 비용을 지출하고 있는 경우, 버전관리 활성화를 제거하는 것만으로도 일정의 비용절감 효과를 달성할 수 있다. 내부 조직에서는 월 비용 $150에 달하는 비용을 절감할 수 있었다.
단, S3에서 비용절감 대상으로 버전관리할 필요 없는 콘텐츠라고 반드시 의사결정되어야 한다. 필자의 조직에서는 버전관리를 허용했으면서도 그 실효성이 거의 없었다. 즉 콘텐츠를 복원하는 일이 전혀 없었으며 오히려 과하게 이미지를 버킷에 중복해서 쌓고만 있었기 때문에 해당 정책을 제거할 수 있었다.
FinOps 커뮤니티에 함께 하실래요?
저는 최근 48%, $36000의 AWS 비용절감을 달성했습니다.
클라우드 비용을 효율화하고 싶은 분들, 비슷한 고민을 나누고 싶다면 제가 운영 중인 AWS-FINOPS-KR Slack 커뮤니티에 참여하세요. 실제 절감 사례, 질문, 전략 공유를 나누실 수 있습니다.