What's New

클라우드 비용 최적화 로드맵 #7 - 스토리지의 사용량을 최적화하는 법

Super Engineer Choi 2024. 12. 11. 16:43

여는 말

안녕하세요. SK텔레콤 최준승입니다. 오늘은 연재 7번째 시간이고요. 주제는 스토리지 영역의 사용량을 최적화하는 법입니다. 여러분도 아시다시피 클라우드 환경에는 아주 다양한 스토리지 서비스가 있고요. 각 서비스별로 데이터를 저장하는 방식과 사용량을 집계하는 특성이 다릅니다. 그 내용은 연재 4회차(스토리지-단가 편)에서 자세히 다뤘으니, 이번 회차를 제대로 이해하기 위해서 선수 과목으로 참고하시는 것도 좋겠네요.

오늘의 목표. 오늘은 Storage 영역의 사용량을 최적화하는 방법을 알아보겠습니다.

4회차 내용을 읽고 오셨다는 가정 하에, 스토리지 계층의 단가를 최적화하는 방법은 어떤 것이었나요? 일단 서비스별 고유의 단가 구조를 이해하는 것이 첫 번째 미션이었고요. 그리고 그 구조에 맞게, 낮은 단가를 제공하는 다양한 저장 계층(Type/Class)을 효과적으로 활용하는 것이 두 번째였습니다. 반면 오늘의 주제인 "스토리지의 사용량 최적화"는 어떻게 해야 할까요? 간단합니다. 스토리지의 사용량을 줄이면 됩니다. "사용량을 줄인다"라는 의미는 데이터를 적게 저장하면 된다는 뜻일까요? 이 표현은 좀 더 정밀하게 정의할 필요가 있습니다. 오늘 본론을 진행하기에 앞서 이 "사용량"에 대한 정의부터 가볍게 시작해 보시죠.

사용량을 측정하는 기준. 서비스마다 사용량을 집계하는 기준이 다릅니다.

AWS가 제공하는 스토리지 서비스를 기준으로, 각 서비스가 위 2가지 유형 중 어디에 속하는지 한번 생각해 봅시다. 먼저 객체 스토리지인 S3는 어떤 유형일까요? 네, 맞습니다. Type-A입니다. S3는 애초에 Provisioning 하는 용량을 지정하지 않을뿐더러, 사용량은 "버킷에 저장한 객체 크기의 총합"으로 집계합니다. 다음으로 블록 스토리지인 EBS는 어떤 유형일까요? 네, 맞습니다. Type-B입니다. EBS 볼륨의 경우 최초 생성 시에 Provisioning 하는 용량을 지정하게 되고요. 그 안에 데이터를 얼마나 저장하느냐와는 상관없이 최초에 Provisioning 한 볼륨 크기를 사용량으로 산정합니다. EFS는 어떻습니까? Type-A고요. DynamoDB의 테이블은 어떻습니까? Type-A입니다. 사실 이렇게 사용량을 다르게 산정하는 이유는 "CSP가 사용자에게 Dedicated 한 영역을 어떤 방식으로 제공하느냐"에서 파생되는 문제인데요. 오늘 주제의 맥락에서는 중요하지 않으니 넘어가도록 하겠습니다.


사용량을 측정하는 2가지 유형을 초반부터 설명드린 이유는, 각 유형에 따라 사용량을 최적화하는 접근 방식이 달라지기 때문입니다. Type-A의 경우, 저장된 데이터의 총량을 인위적으로 줄이면 이것이 바로 스토리지 요금의 사용량으로 반영되기 때문에 즉각적인 절감 효과를 볼 수 있습니다. 또한 Type-A 유형의 서비스는 자동화된 각종 관리기능(Class 관리, Lifecycle, Retention 설정 등)을 (Type-B 유형보다) 풍부하게 활용할 수 있기 때문에 최적화 작업의 접근성 측면에서도 유리합니다. 따라서 오늘 다루는 대부분의 내용은 Type-A 유형의 최적화를 중심으로 하되, Type-B 유형의 최적화는 말미에 다시 한번 정리하도록 하겠습니다.


이제 무엇(=사용량의 측정 기준)을 최적화해야 하는지 확인했으므로, 이어서 "어떻게" 할지를 고민해 봅시다. 즉, 내가 앞으로 데이터의 사용량을 최적화할 예정인데 어떤 관점으로 접근할지를 생각해 보시면 됩니다. 아래 참고 그림을 같이 보시죠.

스토리지 사용량을 최적화하기 위한 접근. 관점 1 : 동일 시점 기준의 사용량 최적화는 어떻게 할까? 관점 2 : 보관 기간 기준의 사용량 최적화는 어떻게 할까? 바라보는 시점을 어떻게 고정하느냐에 따라 접근법이 달라집니다.

스토리지가 담고 있는 데이터의 사용량을 줄이는 방법은 간단합니다. 1) 불필요한 데이터를 삭제 또는 최소화하거나 2) 필요한 데이터를 가능한 작은 크기로 저장하는 것입니다. 먼저 관점 1인 동일 시점 기준으로 생각해 봅시다. 동일 시점에서 불필요한 데이터를 최소화하는 방법은 어떤 것들이 있을까요? 대표적인 사례는 중복을 제거(최소화) 하는 것입니다. 동일한 데이터를 다양한 스토리지 계층(또는 동일한 계층)에 중복으로 저장하는 사례는 생각보다 매우 빈번합니다. 이어서 필요한 데이터를 가능한 작은 크기로 저장하는 방법은 어떤 것이 있을까요? 이는 원본 데이터 구조를 처음부터 최소화하거나 인위적인 방법(압축 등)을 활용할 수 있습니다. 관점 2인 보관 기간 기준으로 최적화 작업은 어떻게 해야 할까요? 간단합니다. 각 데이터의 쓰임새에 따라 보관 기간을 정의하고, 해당 기간이 지난 데이터는 주기적으로 지워주면 됩니다. 보통 이것을 데이터의 Retention 관리라고 합니다.


정리하면 오늘은 크게 3가지 관점으로 나눠서 최적화 주제를 다룰 예정입니다. 첫 번째는 중복 저장을 지양(회피) 하는 방법을 살펴 보고요. 두 번째는 데이터의 Lifecycle 관점에서 Retention 관리를 어떻게 할지를 다뤄보겠습니다. 세 번째는 일종의 부록 편으로 (좀 더 근본적인 관점에서) 데이터 크기 자체를 줄이는 전략을 고민해 보겠습니다. 오늘 주제 자체는 그렇게 어렵지 않으니까요. 사례 중심으로 짧고 간결하게 진행하겠습니다.

첫 번째 전략 : 중복 저장을 피하세요

스토리지의 사용량을 최적화하는 첫 번째 방법은 중복 저장을 피하는 것입니다. 이건 마치 "돈을 모으려면 아껴 쓰면 된다" 수준의 당연한 말로 들리실 수 있겠지만, 데이터를 자유롭게 생성하는데 제약이 없는 클라우드 환경에서는 생각보다 효율적인 전략입니다. 일반 데이터의 중복 이슈는 개별성이 너무 강하기 때문에 차치하고, 오늘은 클라우드 사용자가 공통적으로 겪을만한 중복 사례를 위주로 살펴보도록 하겠습니다.


먼저 백업의 중복 이슈를 생각해 봅시다. 클라우드는 각 스토리지 서비스별로 자동화된 방식의 백업 기능을 제공하기 때문에, 백업에 대한 중복 이슈가 발생하기 쉽습니다. 백업 데이터가 중복되는 케이스는 다음과 같습니다.


① 스토리지 서비스별 자체 백업 데이터와 사용자가 별도로 구성한(예: 3rd Party 솔루션이 쌓는) 백업 데이터가 중복되는 경우

② 스토리지 서비스별 자체 백업 설정의 목적지가 하나가 아닌 복수개로 구성된 경우 (동일 원본으로 2개 이상의 백업본을 생성)

③ 아카이빙 데이터를 기준으로 스토리지 원본과 백업본을 동시에 유지하는 경우

간단한 예시 아키텍처. 사용자로부터 이미지를 전달받아 Processing 후 S3에 저장하는 워크로드 예시입니다.

①번 예시를 위해 AWS 구성도를 간단하게 하나 그려봤습니다. 위 아키텍처는 사용자로부터 이미지를 업로드 받아 EC2 내에서 이미지 프로세싱을 수행한 후, 원본과 결과물을 S3에 복사하는 파이프라인을 설명하고 있습니다. EBS 볼륨 자원의 백업은 AWS Backup을 통해 모든 EBS 볼륨을 대상으로 생성합니다. 이때 백업 정책상 DATA 볼륨의 데이터 중 이미지 파일 외에 다른 데이터는 필요 없다고 가정할 때, DATA 볼륨의 EBS 스냅샷을 생성할 필요가 있을까요? 이미지 파일은 S3에 저장하는 별도의 로직이 있기 때문에, 이 경우에는 DATA 볼륨의 EBS 스냅샷을 생성할 필요가 없습니다. AWS Backup에서 백업 대상을 전체가 아닌 일부로 제한하는 것은 EBS 볼륨에 분류용 태그를 지정하는 식으로 제어하면 됩니다. 자동화된 방식의 백업 기능은 주기적으로 반복되고 보관 기간이 긴 경우도 많기 때문에, 중복되는 영역을 식별하여 백업 범위를 제한하는 것으로 큰 비용 효과를 기대할 수 있습니다.


②번 사례는 동일 원본을 기준으로 복수개의 백업본이 생성되는 경우입니다. AWS 환경을 예로 들면, 보통 AWS Backup과 같이 중앙화된 관리형 서비스로 각 스토리지 계층의 백업 정책을 설계하게 되는데요. 이때 하나의 원본을 대상으로 복수의 백업 계획(Backup Plan)이 정의된 경우가 종종 있습니다. AWS Organization 같이 중앙화된 통합 관리 기능을 사용할 경우 관리 난이도는 더욱 높아집니다. 서비스 자체의 백업 기능과 AWS Backup에 통합된 백업 정책이 중복되는 경우도 있습니다. 사실 서비스별 백업 메커니즘을 깊게 들여다보면 이렇게 백업 정책이 n 개로 중복된다 하더라도 백업 비용이 n 배로 상승하지 않는 경우도 있습니다만, 원칙적으로는 동일 원본을 대상으로 2개 이상의 백업본을 생성할 필요는 없습니다.

1.EFS 서비스의 백업중복 예시. EFS의 Automatic Backups 활성화 시 AWS Backup Plan과 연계되며 타 Backup Plan이 있다면 중복이 발생합니다.

③번 사례는 그리 빈번한 케이스는 아닙니다만, 이런 상황을 가정해 볼 수 있겠네요. 앞으로 사용할 계획이 없는 EC2 인스턴스가 하나 있습니다. 반면 해당 EC2에 붙어있는 EBS 볼륨의 데이터는 당장 쓰지는 않지만 보관이 필요한 상황입니다. 그래서 사용자는 EBS 볼륨의 스냅샷을 생성한 후 EC2 인스턴스를 삭제했습니다. 이때 EC2에 붙어있던 특정 EBS 볼륨이 같이 삭제되지 않고 detach 상태로 남아 있을 때, 해당 객체는 스냅샷 백업본과 중복이 됩니다. 이런 볼륨들은 주기적으로 식별해서 정리해 주는 것이 좋습니다.


자, 그럼 백업에 이어서 로그의 중복 이슈를 살펴보겠습니다. 특히 오늘 주목할 영역은 클라우드의 관리형(managed) 서비스가 만들어 내는 로그입니다. 보통 관리형 서비스는 사용자가 스토리지 계층에 직접 액세스할 수 없는 경우가 많기 때문에, 로깅에 대한 설정을 옵션처럼 밖으로 빼놓았는데요. 어떤 리소스에 어떤 로그를 활성화할지를 비교적 손쉽게 설정할 수 있어 데이터 중복 이슈가 발생하곤 합니다.

AWS 서비스별 설정 가능한 로그 저장소 목록. 각 서비스별로 설정할 수 있는 로그 목적지(저장소)가 다릅니다.

위 표는 AWS의 각 서비스별로 로그를 어떤 목적지로 설정할 수 있는지를 설명한 내용인데요. 예를 들어 WAF 로그는 목적지를 CloudWatch Logs로도 보낼 수 있고 S3로도 보낼 수 있습니다. 다만 두 설정을 동시에 할 수는 없습니다. VPC Flow Logs도 마찬가지입니다. 로그 데이터의 목적지를 CloudWatch Logs / S3 / Firehose 중 한 곳으로 설정할 수 있지만, 동시에 설정할 수는 없습니다. 따라서 이런 경우는 중복 이슈가 발생하기 어렵습니다.

CloudTrail 서비스의 Trail 설정 예시. CloudTrail의 로그는 S3와 CloudWatch Logs에 동시에 설정할 수도 있습니다.

반면 위 그림처럼 CloudTrail의 로그 설정은 중복이 발생하기 쉬운 구조입니다. 하나의 Trail 설정 내에서 S3와 CloudWatch Logs로 동시에 로그를 전송할 수 있습니다. 물론 S3와 CloudWatch Logs는 저장소 특성이 다르기 때문에 두 곳 모두 적재가 필요한 사용자가 있을 수도 있습니다. 하지만 데이터의 중복 관점에서는 로그 적재 이후의 접근성에 따라(athena로 로그 쿼리를 하고 싶으면 S3로 / 이벤트 필터링을 걸고 싶으면 CloudWatch Logs로 저장) 둘 중 한 곳으로 로그 저장소를 제한하는 것이 좋습니다. 다양한 AWS Account 환경을 관찰하다 보면 2개 이상의 Trail이 설정되어 있고 목적지도 2개 이상의 S3로 지정된 케이스도 있는데요. 일부러 의도한 것이 아니라면 이러한 형태의 중복은 제거하는 것이 좋습니다. 단순히 로그 데이터의 저장 요금뿐만 아니라 수집(Processing) 요금도 무시할 수 없기 때문입니다.


백업과 로그에 이어 마지막으로는 데이터의 복제와 공유 관점에서의 최적화 전략을 생각해 보겠습니다. 하나의 상황을 가정해 봅시다. 복수의 Multi-Account 환경에서 A 계정의 S3 버킷에 데이터가 저장되어 있고, 이 데이터는 B 계정과 C 계정의 EC2에서도 액세스가 필요합니다. 이때 사용자는 2가지 전략 중 하나를 선택할 수 있습니다. 첫 번째 전략은 S3 Replication 기능을 이용하여 각 계정의 S3 버킷에 데이터를 복제하는 방법입니다. 이 전략은 복제 비용이 발생함은 물론 복제본의 용량만큼 스토리지의 사용량이 n 배로 증가합니다.

S3 버킷의 복제와 공유 전략. 원본을 하나만 유지하고 참조하느냐, 복제하느냐에 따라 스토리지 총 사용량이 달라집니다.

두 번째 전략은 별도 복제를 사용하지 않고, “B 계정과 C 계정에서” A 계정의 S3 버킷에 직접 액세스하는 방식입니다. 이 경우는 A 계정의 S3 버킷 레벨에서 B 계정과 C 계정의 자원이 접근할 수 있도록 (Bucket Policy와 같은) 접근 권한을 설정해 줘야 합니다. 원본 데이터는 여전히 1벌이기 때문에 (첫 번째 전략과 달리) 스토리지의 전체 사용량은 증가하지 않습니다.


단순히 스토리지의 사용량을 최적화, 다시 말해 중복 데이터를 최소화한다는 관점에서는 두 번째 전략이 유리합니다. 다만 두 전략은 장단점이 있어서, 각자의 상황(데이터 관리주체 요건, 복제 지연, 요청이 몰릴 때의 성능 이슈 등)에 따라 사용자의 선택지는 달라질 수 있습니다. 이런 상황은 비단 S3뿐만 아니라 특정 DB나 데이터 계층을 공용으로 사용할지, 아니면 Replica 형태로 분리/복제해서 사용할지를 판단할 때도 비슷한 결정기준을 따르게 됩니다.


좀 더 글로벌한 관점에서 이런 상황도 고민해 볼 수 있습니다. 글로벌 앱 서비스가 있고, 앱 사용자는 한국에도 있고 미국에도 있고 유럽에도 있다고 가정해 보겠습니다. 이때 각 지역의 사용자에게 서빙하는 이미지는 서울 리전에 위치한 S3 버킷에 저장되어 있습니다. 사용자 경험을 고려하면 미국 사용자는 미주에 위치한 리전에서, 유럽 사용자는 유럽에 위치한 리전에서 S3 객체를 제공하는 것이 가장 좋습니다. 그래서 사용자는 S3의 CRR(Cross-Region Replication) 같은 복제 기능을 고민하고 있습니다. 하지만 다른 방법은 없을까요? 아래처럼 CloudFront 같은 CDN 서비스를 활용해 보는 건 어떨까요?

CDN 서비스를 활용하기. CloudFront 같은 CDN 서비스를 활용하면, 원본을 리전별로 복제할 필요 없이 하나의 원본으로 관리할 수도 있습니다.

위와 같은 CDN 계층을 도입할 경우 사용자 경험을 저해하지 않고 원본 스토리지의 사용량을 최소화할 수 있습니다. 만일 개별화된 응답이 필요하다면 Lambda Edge나 CloudFront Function 계층을 활용할 수도 있습니다. 비용 관점에서 중요한 사실은 CloudFront에서 각 Edge에 데이터를 캐싱 할 때 해당 계층에서 별도의 스토리지 요금을 받지 않는다는 것입니다. 물론 전송 요금(client-edge 간, edge-origin 간)의 유불리는 개별적으로 따져봐야 합니다.

두 번째 전략 : 데이터의 보관 기간을 제한하세요

스토리지의 사용량을 최적화하는 두 번째 방법은 데이터의 보관 기간을 제한하는 것입니다. 보통 스토리지 비용 패턴을 들여다보면 일정한 기울기로 꾸준히 사용량(=비용)이 증가하는 경우가 대부분인데요. 이는 실제 저장하는 데이터량이 늘어서일 수도 있지만, 각 데이터 별로 적절한 생로병사 주기를 정의하지 않았기 때문이기도 합니다. 먼저 영구 보관이 필요한 데이터와 보관 기간을 제한해도 되는 데이터를 분리해 봅시다. 전자는 액세스 패턴에 따라 (다양한 스토리지 계열을 활용해) 단가를 낮추는 전략을 구사하고요. 후자는 일정 기간이 지난 후 자동화된 방식으로 데이터를 삭제하는 로직을 구성합니다. 데이터를 삭제하게 되면 해당 시점부터 스토리지 사용량이 0이 되기 때문에 더 이상의 비용이 발생하지 않습니다. 물론 전자의 단가 최적화 전략과 후자의 사용량 최적화 전략을 동시에 적용할 수도 있습니다.

데이터의 수명 특성에 따른 최적화 전략. 수명주기 내에서는 단가를 최적화하고, 수명주기가 만료되면 삭제를 통해 사용량을 0으로 만듭니다.

그렇다면 수많은 데이터 중에 "보관 기간을 제한해도 되는 것"은 어떤 것들이 있을까요? 백업은 어떨까요? 백업은 적용되는 컴플라이언스 규정에 따라 또는 복구 목표시간(RTO: Recovery Time Objective)에 따라 일정한 보관 기간을 준수해야 하는데요. 만약 그 기준이 1년이라면 1년이 지난 백업본은 보관할 필요가 없습니다. 따라서 1년이 지난 백업본은 정기적으로 삭제해 주는 작업이 필요하죠. 클라우드에서 제공하는 백업 서비스들은 이런 보관 기간을 설정하는 기능이 대개 기본적으로 내장되어 있습니다.

AWS Backup 서비스의 Retention Period 설정 예시. 백업 정책에서 "보관 기간이 지난 백업본"의 자동 삭제를 정의할 수 있습니다.

다음으로 로그 데이터를 떠올려 봅시다. 디버깅 또는 트러블슈팅용 로그를 CloudWatch Logs에 쌓고 있다고 가정해 봅시다. 이런 용도의 로그 데이터를 영구 보관할 필요가 있을까요? 최근 일주일 전까지의 로그만 봐도 된다면, 7일이 지난 로그 데이터는 보관할 필요가 없습니다. 어떤 로그는 최근 90일간 보관이 필요할 수도 있고, 또 다른 로그는 영구 보관이 필요할 수도 있습니다. 그럼 각 Log Group별로 보관 주기를 다르게 설정하여 관리할 수 있습니다. AWS의 CloudWatch Logs의 경우 아래처럼 Log Group별로 Retention 기간을 정의할 수 있습니다.

CloudWatch Logs의 Retention Period 설정 예시. 각 Log Group의 로그 중 Retention 기간이 지난 데이터는 삭제됩니다.

모든 최적화 작업은 투입되는 리소스 대비 효용을 감안해야 하는데요. 위 예시처럼 각 서비스에 자체 내장되어 있는 보관 주기 기능을 활용하면, 큰 노력을 투입하지 않고도 귀찮은 수명주기 관리 작업을 한방에 자동화할 수 있습니다. 보통 S3처럼 낮은 저장 단가를 제공하는 객체 스토리지에는 각종 로그나 백업 데이터를 저장하는 경우가 많은데요. S3 서비스 또한 내장된 Lifecycle 기능을 통해서 데이터의 수명 주기를 정의할 수 있습니다. 참고로 S3의 Lifecycle 기능은 동일 버킷 내에서도 특정 prefix나 객체 크기(min/max) 조건에 따라 그 대상을 개별 정책으로 제어할 수도 있습니다.

S3의 Lifecycle 기능에서 보관 기간을 설정하는 예시. 모든 객체는 업로드 후 180일 이후에 삭제(expire) 해주세요.

S3 얘기가 나온 김에 한 가지 더 팁을 드리면, S3에는 multipart upload라는 로직이 있는데요. 해당 로직은 대용량 파일 하나를 업로드하기 위해 단위 Parts를 여러 개의 스레드로 나눠서 업로드한 후 이어 붙이는 작업을 해주는 기능입니다. 간혹 전체 업로드 작업이 완결되지 않으면 잔여 Parts가 그대로 남아서 표준 S3 저장 요금이 부과되는 경우가 종종 있는데요. (참고로 해당 사용량은 S3 Storage Lens 대시보드에서 확인할 수 있습니다.) S3 서비스는 이 계층의 Lifecycle 관리도 아래와 같이 자동화된 방식으로 제어할 수 있습니다. 이런 지엽적인 사례를 언급하는 이유는 데이터의 수명주기 관리는 "현재 비용이 발생 중인 모든 스토리지 계층"을 대상으로 해야 하기 때문입니다.

incomplete multipart uploads 객체 관리 정책 예시. 7일이 지난 불완전 upload part는 알아서 삭제를 부탁드립니다.

이번 장을 정리합니다. 클라우드 환경에서 스토리지의 사용량을 최적화하는데 효과적인 전략은 각 데이터별로 보관 기간을 제한하는 것입니다. 데이터별로 수명주기를 정의했다면, 해당 기간이 지난 데이터는 자동화된 방식으로 삭제해야 합니다. 이 반복 작업은 별도 구현도 가능하지만, 스토리지 서비스가 자체 제공하는 관리기능을 적극적으로 활용하는 것이 좋습니다.

세 번째 전략 : 저장 형식을 최적화하세요

마지막은 좀 더 근본적인 접근을 해보려고 하는데요. 스토리지의 사용량을 조정하는 3번째 방법은 "저장 형식을 최적화" 하는 것입니다. 쉽게 말해 사용량으로 집계되는 원본 데이터의 크기를 줄여보려고 합니다. 동일한 정보의 데이터를 저장하는데 더 적은 크기를 차지하는 방법은 무엇이 있을까요? 쉽게 생각해 볼 수 있는 방법은 적절한 파일 포맷을 선택하는 것입니다. 기본적으로 압축을 지원하는 포맷도 좋습니다. 예를 들어 (모든 상황에서 그런 것은 아니지만) 동일한 데이터를 parquet 포맷으로 저장 했을 때, csv나 json 포맷에 비해 더 적은 용량을 차지합니다.


좀 더 공격적인 전략도 가능합니다. 예를 들어 csv나 json 같은 파일을 압축해서 저장하는 것은 어떨까요? 텍스트 배열 특성에 따라 다르겠지만 일반적으로 zip 형식으로 압축할 경우 파일 크기를 80%에서 90%까지 줄일 수 있습니다. 비교적 사이즈가 큰 비디오 원본은 어떻습니까? H.265와 같은 최신 코덱을 사용할 경우 동일 화질에서 더 높은 압축률로 파일 크기를 효과적으로 줄일 수 있습니다.

창의적인 접근. S3 서비스의 과금 특성을 고려하여, 위와 같은 전략을 구사할 수도 있습니다.

스토리지의 과금 특성과 결합하여 다음과 같은 최적화 케이스도 고려해 볼 수 있습니다. S3에 128KB 미만의 객체(비압축 형식)가 다수 있다고 가정해 봅시다. 해당 객체는 현재 모두 Standard Class로 저장되어 있습니다. 참고로 S3의 Standard-IA Class는 최소 과금 Size가 128KB라서, 해당 크기보다 작은 객체도 모두 128KB 기준으로 과금합니다. 따라서 Standard-IA의 저장 단가는 Standard의 단가보다 낮지만, 최소 과금 Size 제약조건으로 인해 Standard-IA로 전환했을 때 실익이 없습니다. 하지만 해당 객체들을 10MB 단위로 압축해서 단일 파일로 만들고, 그것을 Cold 계열의 Storage Class로 전환하면 어떨까요? 먼저 파일 묶음을 압축했을 때 원본 크기가 줄어들 것이고(=사용량 감소), 해당 파일을 Cold 계열의 Class로 전환했을 때 저장 비용(=단가 감소)을 한 번 더 최적화할 수 있습니다. 물론 1회 발생하는 전환 비용(압축 및 Class 전환)을 감안하여, 이후에 줄어드는 저장 비용이 충분히 상쇄되는지는 사전 검토가 필요합니다. 또한 해당 데이터를 활용하는(읽어 들이는) 계층의 편의성이나 성능 요소도 함께 고려되면 좋겠죠.


이번에는 저장 형식의 최적화 관점에서 로그 데이터의 양을 줄여 봅시다. 압축과 같은 인위적인 방법은 제외하고 로그의 절대적인 양을 줄이려면 어떻게 해야 할까요? 가장 근본적인 방법은 애초에 필요한 로그만 생성하는 것입니다. 특히 클라우드의 각종 관리형 서비스들은 저장/수집하는 로그 항목이나 로그 레벨을 커스텀 할 수 있는 기능을 제공하는데요. 각자의 용도에 따라 이런 설정을 부지런히 만져주는 것이 좋습니다.

Lambda 서비스의 로깅 설정 예시. 사용자가 설정한 Log Level에 따라 로깅 대상 이벤트가 달라집니다.

위 예시는 Lambda 서비스의 로깅 설정 예시입니다. 예를 들어 Application Log Level을 INFO로 설정할 경우 상위 레벨인 TRACE나 DEBUG 수준의 레코드는 로깅되지 않습니다. 여기서 로깅되지 않는다는 의미는 수집의 범위를 포함하고 있기 때문에, 사용자는 수집 비용과 저장 비용을 동시에 최적화할 수 있습니다. 아래 추가적인 예시는 EKS Control Plane의 로깅 설정 화면입니다. 이 설정에서는 Log Level이 아닌 "로그가 수집/저장되는 항목"을 선택적으로 조정할 수 있고요. 예를 들어 사용자가 모든 항목의 로그가 필요하지 않고, 보통 로그양이 많은 API Server / Audit / Authenticator는 제외하고 싶다면 3개 항목의 로그 설정을 Disable 상태로 변경하면 됩니다.

EKS Control Plane의 로깅 설정 예시. 모든 항목을 다 Enable할 필요가 있을까요? 필요한 것만 설정합시다.

이외에도 다양한 로그 최적화 기법이 있습니다. 로그는 비슷한 포맷의 데이터가 반복되는 특성이 있기 때문에, 해당 표준 형식을 구성하는 모든 요소가 최적화의 대상이 될 수 있습니다. 각 리소스의 태그 값이 로그에 포함되어 있다면, 로그 데이터의 크기를 줄이기 위해 태그 값의 글자 수를 제한할 수도 있습니다. 중요한 것은 이러한 개선 활동이 데이터의 총량이 충분히 크다는 전제 조건에서 유효하다는 것입니다. 물론 예방 차원에서 진행할 수도 있지만 기대 효과가 크지 않다면 개선 활동의 ROI가 나오지 않는 소모적인 활동이 될 수도 있습니다.

마치며

이제 마칠 시간입니다. 오늘은 스토리지의 사용량을 최적화하기 위한 3가지 방안을 살펴봤습니다. 오늘 소개 드린 3가지 접근법은 이 중 하나를 선택하는 것이 아닌 병렬적으로 동시에 적용할 수 있는 것들이기 때문에, 순차적으로 적용할 경우 기대 효과는 생각보다 클 수도 있습니다.

오늘의 주제 복습. 스토리지의 사용량을 최적화하는 3가지 방법은 다음과 같습니다. 1) 중복 저장을 피하세요. 2) 보관 기간을 제한하세요. 3) 저장 형식을 최적화하세요.

글 초반에 스토리지의 사용량을 측정하는 2가지 서비스 유형을 소개해 드렸는데요. 단위 객체의 사용량을 줄이면 바로 과금에 반영되는 Type-A 유형(AWS의 S3, EFS 등)은 비교적 최적화 작업이 수월합니다. 반면 EBS 볼륨처럼 생성한(Provisioned) 그릇의 크기에 과금하는 유형은, (오늘 3가지 방안을 통해) 데이터 크기를 줄였다고 하더라도 그 효과가 즉시 발생하지 않습니다. 이 경우에는 더 작은 크기의 EBS 볼륨을 새로 생성하고, 기존 데이터를 복제하는 번거로운 작업이 필요합니다.


제가 오늘 강조 드리고 싶은 메시지는 스토리지의 사용량 최적화 또한 투입하는 노력 대비 기대효과가 큰 영역부터 시작해야 한다는 것입니다. AWS 환경에서의 제 경험으로 비추어 볼 때, 웹 콘솔에서 제어할 수 있는 (아주 제한적인) 영역의 작업만으로도 스토리지 비용의 상당 부분을 절감할 수 있었습니다. 사용자의 개별 데이터를 제외하고 AWS 환경에서 공통적으로 발생하는 데이터들로 최적화 범위를 제한한다고 하더라도, 그 효과가 매우 큰 경우가 많았습니다.


참고로 오늘은 스토리지의 저장 비용을 위주로 내용을 전개했지만, 스토리지 서비스가 단순히 저장 비용으로만 구성된 것은 아닙니다. 요청 비용도 있고요. 관리 비용도 있습니다. 더구나 이런 부대 비용이 저장 비용을 상회하는 경우도 비일비재합니다. 따라서 스토리지의 사용량을 최적화 할 때에는 "각 단위비용 항목이 집계하는 사용량"을 종합적으로 고려할 필요가 있습니다.


다음 8회차는 네트워크의 사용량을 최적화하는 법입니다. 사실 컴퓨팅이나 스토리지에 비해 네트워크 영역의 사용량 최적화는 소개드릴 기법이 많지는 않은데요. 연재물 구성상 본론(단가 편 3회차, 사용량 편 3회차)이 끝나는 회차니 이야기를 잘 마무리해 보려고 합니다. 이어 9회차와 10회차에서는 제가 하고 싶은 이야기를 위주로 알찬 부록을 만들어 보겠습니다. 그럼 8회차에서 뵙겠습니다. 끝!

 

▶ 더 읽어보기

 

▶ 최준승 님 / Cloud Architect 팀 / jsch@sk.com