AWS 기술 블로그

Amazon DynamoDB 비용 최적화 방법 살펴보기

Amazon DynamoDB는 모든 규모에서 고성능 애플리케이션을 실행하도록 설계된 완전관리형 서버리스 키-값 NoSQL 데이터베이스입니다. DynamoDB의 핵심 비용은 데이터를 읽고 쓸 때 발생하는 I/O 용량과 저장되는 데이터의 양인 스토리지 항목에서 시작됩니다.

이 블로그에서는 DynamoDB에 대한 핵심 비용 구조를 설명하고, 서비스의 라이프 사이클에 따라 설계, 개발, 운영 단계 별로 비용을 최적화 할 수 있는 방법을 안내합니다. Amazon의 Flywheel 모델처럼 DynamoDB를 사용할 때도 한번 개발 이후 모든 것이 끝나는 것이 아닌, 서비스가 만들어진 이후부터 종료될 때까지 지속적으로 비용을 최적화하며 선순환 할 수 있어야 합니다.

DynamoDB 핵심 비용 구조

  1. 용량 모드 비용
    • RCU/WCU 과금 단위
      • 읽기는 각 읽기 작업에 대해 4KB, 쓰기는 각 쓰기 작업에 대해 1KB 단위로 과금됩니다. 읽기 용량 유닛(Read Capacity Unit, RCU)은 테이블에서 데이터를 읽을 때 발생하는 각 API의 용량 단위입니다. 예를 들어, 최대 4KB 크기 아이템의 하나의 읽기 요청은, 강력한 일관된 읽기(Strongly consistent read)는 1 RCU를, 최종적 일관된 읽기(Eventually consistent read)는 0.5 RCU를 또는 트랜잭션 읽기(Transactional read)에서는 2 RCU를 소모합니다. 쓰기 용량 유닛(Write Capacity Unit, WCU)은 테이블에 데이터를 조작할 때 발생하는 각 API의 용량 단위입니다. 최대 1KB 크기 아이템의 쓰기 요청은 1 WCU를, 트랜잭션 쓰기(Transactional write)에서는 2 WCU를 소모합니다.
    • 온디맨드 모드 / 프로비저닝 모드의 기본 개념
      • DynamoDB는 프로비저닝 모드와 온디맨드 모드라는 두 가지 형태의 용량 모드를 제공합니다. Amazon EC2 인스턴스로 예를 들어보면, 프로비저닝 모드는 EC2 인스턴스를 시작하면 인스턴스의 사용율과 관계없이 초 당 비용이 과금되며 애플리케이션 오토 스케일링을 이용해 트래픽 양에 따라 탄력적으로 인스턴스 개수가 조정되며 가변 비용을 지불하는 것과 같이, 테이블의 WCU와 RCU를 애플리케이션 오토 스케일링을 이용해 자동으로 조정할 수 있습니다. 온디맨드 모드는 용량 계획 없이 초당 수천 개의 요청을 처리할 수 있는 유연한 청구 옵션입니다. 예를 들면, AWS Lambda 함수가 호출 건당 비용이 과금 되는 방식처럼 DynamoDB에서도 읽기 및 쓰기 요청에 대해 요청당 지불 가격을 제공하므로 사용하는 만큼에 대해서만 비용을 지불하면 됩니다.
  2. 데이터 스토리지
    • 스토리지는 GB-월 단위로 과금되며 테이블과 인덱스에 저장된 데이터의 양을 나타냅니다. 2021년 부터 DynamoDB는 기존의 DynamoDB Standard 이외에 Standard-Infrequent Access(DynamoDB Standard-IA) 스토리지 클래스를 제공합니다. 두 스토리지 클래스는 성능 차이가 없으며, 용량 모드와 스토리지의 비용 모델이 다른 차이점을 갖고 있습니다.
  3. 그 외 (선택사항)
    • 그 외에는 고객의 선택에 따라 글로벌 테이블, 백업, 복구, PITR(Point in time recovery) 등을 사용하면 추가 비용이 발생되는 구조이며, 자세한 비용 및 항목은 프로비저닝된 모드온디맨드 모드 가격 페이지의 ‘DynamoDB 세부 기능 요금’란을 참조하시면 됩니다.
  4. 비용 구조를 가시화 할 수 있는 도구
    • AWS Cost Explorer의 기본 보기는 읽기/쓰기 용량 및 스토리지와 같은 사용된 리소스 비용을 보여주는 차트를 제공합니다. 아래 그림처럼 월별 또는 일별 사용량을 항목 별로 그룹화하도록 선택할 수 있고 스토리지, 읽기, 쓰기 및 기타 기능의 비용도 세분화하여 비교할 수 있습니다. 또한, DynamoDB 각 테이블에 태그(Tags)를 지정하면 테이블 별 비용도 가시화가 가능합니다.

비용 최적화 포인트 소개

DynamoDB의 서비스의 설계/개발/운영 단계에서 비용 최적화를 할 수 있는 포인트가 있습니다.

  1. 설계 단계
    • 액세스 패턴
      • 만약 하나의 아이템에 Price와 Description이라고 하는 두 개의 어트리뷰트가 함께 존재한다고 가정합니다. Description은 자주 변경되지 않지만 데이터 크기가 크고 Price는 크기가 작지만 변경이 자주 일어난다면, 둘을 다른 아이템으로 분리하면 매번 데이터 변경마다 큰 비용을 지불할 필요가 없게 됩니다. 변경이 잦은 데이터와 자주 변경되지 않는 데이터는 아이템 레벨에서 구분할 수 있다면 좋습니다.
      • 다음은 몇 달에 한번 테이블에서 대량 읽기와 같이 자주 사용되지 않는 액세스 패턴을 위해 GSI를 만들기보다는 필요할 때 Amazon S3로 Export하는 기능을 사용하거나 SCAN API를 이용하는 것이 비용 효율적일 수 있습니다.
      • 다음은 예를 들어 A, B, C 라는 3개의 리전에서 글로벌 테이블을 사용하고 있다고 가정을 해보겠습니다. A리전에서 1 rWCU를 소모해 하나의 아이템을 추가했다면 B와 C리전에는 각각 1 rWCU를 소모해 데이터를 비동기 복제합니다. 데이터를 조작할 때 복제를 위한 메커니즘은 하나의 리전에서 TTL로 인해 삭제되는 아이템에도 동일하게 동작합니다. 하지만 리전 단위의 테이블이라면 애플리케이션 요구조건이 가능한 경우 WCU 비용을 지불하며 불필요한 데이터를 삭제하는 것 보다는 무료인 TTL기능을 사용하는 것이 좋습니다.
      • ACID를 지원하는 트랜잭션 기능은 내부적으로 2단계 커밋 프로토콜(Two Phase Commit, 2PC)을 통해 실행됨에 따라 동일 요청을 BATCH API로 실행할 때보다 WCU/RCU 비용이 2배로 증가합니다. 그래서 모든 BATCH API를 트랜잭션으로 변경하기 보다는 일부 트랜잭션이 정말 필요한 부분에 사용을 고려해야 합니다.
      • 다음으로 아이템 수정 후 즉시 최신 데이터를 조회할 수 있는 강력한 일관된 읽기보다, 조회 시점에 따라 이전 데이터가 조회될 수도 있는 최종적 일관된 읽기는 절반의 RCU를 소모합니다. 은행 송금이나 게임에서 아이템 구매 후 즉시 구매한 아이템이 보여야 하는 것과 같은 특정 상황이 아니라면 읽기 API들은 기본값인 최종적 일관된 읽기 통해 비용을 절감할 수 있습니다.
  2. 개발 단계
    • 스키마 디자인
      • NoSQL에서 어트리뷰트 이름을 줄여서 쓰는 것은 왜 중요한가?
        • 대부분 NoSQL 데이터베이스들은 스키마리스한 특징을 갖습니다. 관계형 데이터베이스에서는 일반적으로 fullName, homeAddress와 같이 의미있는 어트리뷰트 이름을 갖는 것이 일반적입니다. 왜냐하면 테이블의 스키마는 고정되어 있기 때문에 어트리뷰트의 이름은 시스템 테이블에 한번만 저장되고, 실제 스토리지엔 어트리뷰트의 값만 저장됩니다. 하지만 대부분 NoSQL 데이터베이스들은 모든 아이템의 어트리뷰트 이름과 값을 함께 스토리지에 저장하는 방식으로 스키마리스를 제공합니다. 그래서 어트리뷰트 이름의 크기가 줄어들면 스토리지 사용량, WCU/RCU 사용량 그리고 네트워크 전송 시간이 줄어듭니다.
      • 보조 인덱스를 만들 때는 ALL이 아닌 필요한 어트리뷰트만 선택
        • DynamoDB에서 보조 인덱스를 생성할 때 ALL, KEYS_ONLY, INCLUDE라는 세 가지 옵션을 사용할 수 있습니다. 예를 들어, 기본 테이블의 아이템 크기가 3KB인 경우 GSI(Global Secondary Index)를 KEYS_ONLY 옵션으로 200 bytes로 만들었을 경우와 ALL옵션으로 3KB로 만들었을 경우를 가정해 봅니다. 매번 GSI와 연관된 아이템이 변경될 때마다 선택에 따라 GSI에서 전자는 1 WCU가 소모되며, 후자는 3 WCU라는 큰 차이의 WCU가 소모됩니다. 리버스 인덱스 형태인 KEYS_ONLY를 선택할 경우 기본 테이블에서 한번 더 읽기를 해야할 수 있지만, 기본 테이블의 데이터 변경이 많은 경우라면 두 번 읽는 것이 더 저렴할 수 있고 꼭 모든 API가 데이터베이스 호출 1번에 끝날 필요는 없습니다.
  3. 운영 단계
    • 용량 모드 선택 고려 사항
      • 프로비저닝 모드와 오토스케일링
        • 서비스가 피크 시간과 최저 사용 시간이 존재하고, 종일 사용되는 일반적인 프로덕션 환경에서는 프로비저닝 모드와 오토스케일링을 사용해 데이터베이스 영역을 쉽게 고정 비용에서 가변 비용으로 만들 수 있습니다. 대표적으로 EC2에서 많이 사용하시는 애플리케이션 오토 스케일링을 이용해, DynamoDB는 WCU/RCU 용량을 사용자가 지정한 최소/최대값 사이에서 트래픽에 따라 오토스케일링 합니다.
        • 오토스케일링을 사용할 때 지정하는 Target Utilization은 기본 값이 70%이고, 20-90 사이에서 설정하면 됩니다. 예를 들어, 이 값을 70%로 설정하면 실제 소비되는 WCU/RCU 값(그림의 주황색)이 프로비저닝 할 WCU/RCU 값(그림의 파란색)의 70%를 유지한다는 의미이며, 90%로 했을 때는 파란색과 주황색의 간격이 좁아지고, 50%로 했을 때는 간격이 넓어집니다. 그렇다면 비용 최적화를 위해 무조건 높은 값을 설정하는 것이 낫다고 예상하실 수 있지만, 순간 스파이크 트래픽이 있는 웹 서비스에서 이 결정은 다량의 쓰로틀링을 유발하게 됩니다. 만약, 스파이크 없이 N개의 기기에서 주기적으로 상태 값을 업데이트하는 트래픽이 유입되는 IoT 같은 워크로드라면 높은 값을 사용해 비용을 최적화할 수 있습니다.
        • 초기의 DynamoDB 프로비저닝 모드는 설정된 WCU/RCU를 테이블의 파티션의 개수로 나눠서 관리했기 때문에 하나의 파티션에 트래픽이 조금만 몰려도 즉시 쓰로틀링을 만들어냈습니다. 하지만 현재 DynamoDB에서 사용되고 있는 Adaptive capacity는 다른 파티션에서 미사용되고 있는 WCU/RCU를 즉시 트래픽이 몰리는 파티션에서 사용할 수 있고, 위 그림의 파란색과 주황색 사이의 현재부터 최대 5분전까지 사용되지 않은 WCU/RCU를 토큰 버킷에 저장해두었다가 스파이크 트래픽이 유입될 때 즉시 사용할 수 있는 Bursting 기능을 이용해 쓰로틀링을 줄일 수 있습니다. 정리하면, Target Utilization의 특성을 이해하고 내 워크로드의 특성에 따라 값을 조정해나가야 합니다. 또한, 각 파티션은 매초 1,000 WCU/3,000 RCU 이상의 성능을 낼 수 없는 제약을 갖고 있기 때문에, 여전히 키 디자인은 매우 중요합니다.
      • 온디맨드 모드
        • 일반적으로 애플리케이션 오토 스케일링이 동작할 수 없는 급격한 스파이크 트래픽이나 종일 사용되지 않는 개발/스테이징/검증과 같은 환경에서는 온디맨드 모드를 권장합니다. 온디맨드 모드는 “Set it and forget it”이라는 점에서 매우 훌륭하지만 DynamoDB의 예약용량(Reserved Capacity, RC)을 사용할 수 없는 점도 비용 관점에서는 중요한 포인트입니다.
      • 두 용량 모드 간의 전환은 무중단으로 하루에 한번 가능합니다.
    • 스토리지 클래스 고려 사항
      • DynamoDB는 2021년 re:Invent를 기점으로 두 가지 스토리지 클래스를 제공합니다. 기존의 Standard 스토리지 클래스는 여전히 대부분 고객의 워크로드에 적합합니다. 하지만 대표적으로 이커머스의 구매 이력, 소셜 네트워크 서비스의 게시글처럼, 서비스가 시작되고 종료될 때까지 삭제할 수 없고 지속적으로 쌓이는 데이터 특성을 갖는 워크로드는 아래 그림처럼 서비스가 성장하며 용량 비용보다 스토리지 비용이 커지는 지점이 발생하게 됩니다. 태그를 통해 각 테이블의 비용을 모니터링 하며 이런 워크로드는 스토리지 비용이 전체의 50%가 넘으면 Standard-IA 스토리지 클래스로 변경을 고려합니다. DynamoDB 스토리지 클래스를 Standard에서 Standard-IA로 변경 시 스토리지 비용이 60% 줄고, 용량 비용이 25% 늘어나는 비용 모델의 변경이기 때문에, 성능의 차이가 없으며 무중단으로 적용됩니다. 스토리지 클래스 변경은 한달에 한번 가능하고, 클래스 변경 후 Cost Explorer에서 하루 이틀 비용을 모니터링 해보며 비용이 늘었다면 즉시 기존으로 돌아올 수 있어 위험부담이 적습니다. 마지막으로 Standard-IA를 적용하면 모든 용량 모드에서 예약용량을 사용할 수 없기 때문에, 변경 전 남아있는 예약용량 규모와 기간을 통해 내 워크로드의 Standard-IA 적용 시점을 계산해야 합니다.
    • 예약 용량 구매 전략
      • DynamoDB는 1년 혹은 3년 단위의 예약 용량 구매를 통해 최대 54%(1년) ~ 77%(3년)의 용량 할인을 받을 수 있습니다. 예약 용량은 각 리전에서 100 WCU 혹은 100 RCU 단위로 구매할 수 있으며, 프로비저닝 용량 모드와 Standard 스토리지 클래스를 사용하는 테이블에만 적용됩니다.
      • 예약 용량을 구매하실 때는 1년에 한번 모든 용량을 구매하시기 보다는, 전체 DynamoDB 비용 중 예약 용량으로 커버할 Target KPI를 설정하신 후 매달 비용을 모니터링하며 주기적으로 재구매하는 FinOps 전략을 통해 RC 구매 위험 부담을 낮추시길 권장합니다.
    • 미사용 GSI 삭제
      • Amazon CloudWatch의 Consumed RCU 메트릭을 이용해 지난 30일 동안 RCU 사용량이 없는 GSI들을 추출할 수 있으며, 언제든 미사용 GSI를 삭제 할 수 있습니다.

마치며

이번 블로그에서는 서비스의 설계 → 개발 → 운영 단계 별로 DynamoDB 비용을 최적화 할 수 있는 방법을 알아봤습니다. 마지막으로 DynamoDB를 사용하며 어려움을 겪고 계시다면, 언제든 함께 일하고 계신 AWS 어카운트팀을 통해 DCAD(Database Clinic in A Day)를 요청하세요.

DCAD는 DynamoDB immersion day 교육을 이수한 고객을 대상으로 DynamoDB 전문가들과 함께 실제 고객 워크로드를 진단해보는 반일과정 시간입니다. 키 디자인, 성능, 비용 최적화 등 DynamoDB를 사용하며 겪고 있는 어려움을 주제로 DCAD를 요청할 수 있습니다.

Hyuk Lee

Hyuk Lee

이혁 DynamoDB 솔루션즈 아키텍트는 DynamoDB의 기능을 이용해 고객의 아키텍처 현대화를 도와드리고 있습니다.

Jin Seop Lim

Jin Seop Lim

임진섭 Technical Account Manager(TAM)은, Enterprise 고객이 AWS에서 효율적으로 솔루션을 구축하고 클라우드 운영을 최적화 할 수 있도록 전략의 수립 및 이행을 지원합니다. AWS 환경을 양호하게 유지할 수 있도록 적극적으로 지원하고 전략적 기술 방향을 제공합니다. 또한 고객과 긴밀한 관계를 구축하여 고객의 비즈니스 및 운영 요구 사항과 기술적 과제를 이해하고 고객이 AWS에서 최고의 가치를 달성하는데 도움을 드리고 있습니다.