AWS 기술 블로그

Amazon DynamoDB의 서비스 오픈 전 체크포인트와 오픈 전략

최근 서비스를 구성 할 때 원활한 확장성과 운영 관리에 대한 부담을 줄이는 형태로 서비스를 구성하고 있습니다. 서비스를 구성할때에는 오픈 전 장애를 최소화 하고 안정적으로 운영하기 위하여 여러 부분을 검토 합니다. 서비스 오픈 후 변경을 하기 위해서는 더 많은 노력이 필요합니다. 또한 서비스 오픈 이후 갑작스러운 스케일 작업이나 관리 작업 등 관리에 따른 부담이 많이 발생이 됩니다. 이를 위하여 Amazon DynamoDB를 활용한다면 많은 부분에 대한 관리 부담을 줄일 수 있습니다.

이 블로그에서는 DynamoDB를 활용하여 서비스 오픈 전 확인해 보면 좋은 체크포인트와 서비스 오픈에 필요한 전략을 확인할 수 있습니다.

DynamoDB 소개

DynamoDB는 Key-Value 기반의 완전관리형 NoSQL 데이터베이스 서비스로서 원활한 확장성과 함께 빠르고 예측 가능한 성능을 제공합니다. DynamoDB는 분산 데이터베이스를 운영하고 크기 조정하는데 따른 관리 부담을 줄여서 하드웨어 프로비저닝, 설정 및 구성, 복제, 소프트웨어 패치 또는 클러스터 크기 조정에 대해 걱정할 필요가 없게 합니다.

서비스 오픈 전 체크포인트

데이터 액세스 패턴

데이터 액세스 패턴은 내 애플리케이션 입장에서 “어떤 파라메터로 어떤 데이터를 조회/조작한다”를 모두 명세한 것입니다. 예를 들면, “고객ID로 고객 정보를 조회한다” 혹은 “주문ID로 주문에 대한 상세 정보를 조회한다”입니다. 액세스 패턴에 대한 자세한 설명은 이 영상을 참고할 수 있습니다. 애플리케이션이 DynamoDB의 데이터를 조작하는 모든 명세를 이해하고 시작해야 한다는 점이 RDBMS와 매우 큰 차이라고 볼 수 있습니다. RDBMS는 런타임에 조인 연산을 이용해 언제든 원하는 결과를 만들어낼 수 있지만, 대부분 NoSQL은 조인 연산을 지원하지 않기 때문에 모든 액세스 패턴을 알고 키 디자인을 시작해야 합니다. 그래서 요구사항이 매우 빈번하기 변경되는 초기의 비즈니즈 단계에서는 변화에 더욱 유연하게 대응할 수 있는 RDBMS가 적절한 선택이 될 수 있습니다.

DynamoDB는 두 가지 처리량 모드를 가지고 있습니다. 모든 처리량 모드에서 키 디자인에 따라 스로틀링이 발생될 수 있습니다. DynamoDB는 각각의 데이터를 파티션에 분산하여 저장 합니다. 파티션의 분배는 파티션 키를 통하여 설정이 되는데 모든 파티션으로 트래픽이 최대한 고르게 분배가 될 수 있도록 하는 키 디자인 전략이 가장 중요 합니다.

다음 다이어그램은 여러 파티션에 걸쳐 데이터가 저장된 Pets라는 테이블을 보여줍니다. 테이블의 기본 키는 AnimalType 입니다. DynamoDB는 해시 함수를 사용하여 새 항목을 저장할 위치를 결정합니다. 이 경우 문자열 Dog의 해시 값이 기준으로 사용됩니다. 항목은 정렬 순서대로 저장되지 않습니다. 각 항목의 위치는 파티션 키의 해시 값으로 결정됩니다.

서비스 할당량 관리

서비스를 운영하다 보면 빠르게 확장 혹은 증설이 필요할 수 있습니다. 민첩하게 확장이 필요한 상황에서 AWS 에서는 다양한 사이즈의 서비스 할당량을 관리할 수 있습니다. 서비스 할당량을 늘리기 위해서는 직접적인 작업이 필요합니다. 또한 서비스 할당량을 늘리는데는 일정 시간이 필요하기 때문에 미리 서비스 할당량을 알맞게 늘려 두면 민첩하게 서비스 확장을 할 수 있습니다. 서비스 할당량을 늘릴때는 같이 사용되는 구성에 대한 할당량도 같이 늘려주면 더욱 원활하게 서비스 확장이 가능 합니다. 예를들어 Amazon DynamoDB StreamsAWS Lambda를 함께 활용한다면 Lambda도 함께 증설이 필요합니다.

서비스 할당량을 늘리는 전략도 중요합니다. 서비스 할당량을 늘리는것은 처음부터 한번에 많이 늘릴 수 없습니다. 마치 신용카드의 사용 금액 할당량을 늘리는 것과 같습니다. 카드 금액도 일정 금액 이상 사용을 하면서 카드 활용을 잘 하는 경우 한도 승인이 되는 것 처럼 서비스 할당량 증가도 마찬가지 입니다. 서비스 할당량은 특정수치 이상을 사용하거나 수치화 된 사용 예정량이 있는 경우 내부 검토에 의하여 할당량을 늘려주게 됩니다. 여러가지 데이터가 할당량을 늘리는데 사용되기 때문에 미리 할당량을 늘려주어야 한계치 까지 사용하여 스로틀링이 발생하기 전에 미리 늘려 둘 수 있습니다.

로컬 보조 인덱스 사용(Local Secondary Index, LSI)

일부 애플리케이션은 베이스 테이블의 프라이머리 키(Primary Key)만 사용하여 데이터를 쿼리하지만, 보조 인덱스가 유용한 상황이 있습니다. 애플리케이션에서 정렬 키(Sort Key)를 선택할 수 있도록 DynamoDB 테이블에 최대 5개의 로컬 보조 인덱스를 생성하고 이러한 인덱스에 대해 Query 또는 Scan 요청을 실행할 수 있습니다.

로컬 보조 인덱스를 사용하면 강력한 일관된 읽기(Strongly Consistent Read)를 사용할 수 있습니다. 하지만 여러 제약사항으로 인하여 서비스에 반드시 필요한 부분인지 확인이 필요합니다. 로컬 보조 인덱스의 경우 항목 컬렉션 사이즈의 한계가 10GB로 제한이 됩니다. 서비스 요구 사항에 따라 로컬 보조 인덱스를 사용해야 하는 경우라면 ReturnItemCollectionMetrics 파라미터를 SIZE로 설정하여 지속적인 항목 컬렉션 사이즈 모니터링을 해야만 서비스에 안정적으로 활용할 수 있습니다. 또한 로컬 보조 인덱스의 경우 테이블 생성 시에만 추가가 가능하고 테이블에 생성된 다음에는 제거가 불가능 합니다. 따라서 만약 강력한 일관된 읽기가 필요하다면 TransactWriteItems API를 이용해 베이스 테이블에 직접 LSI의 내용을 구현하는 방법하고 불필요 시 제거하는 방법도 고민해볼 수 있습니다.

TTL (Time To Live)

DynamoDB에서는 TTL(Time To Live) 기능을 제공 합니다. DynamoDB의 TTL은 더 이상 필요없는 아이템을 삭제하기 위한 비용 효율적인 방법입니다. TTL은 언제든 활성/비활성화가 가능하고 아이템별 만료 타임스탬프를 정의하면 동작합니다. DynamoDB는 쓰기 처리량(Write Capacity Unit, WCU)을 소비하지 않고 만료 후 며칠 내에 만료된 아이템을 자동으로 삭제합니다.

테이블 데이터에 Unix epoch 시간를 활용하여 현재 이전의 데이터만 볼 수 있는 로직을 활용하고 있다면 TTL 활용을 통하여 WCU 사용량 없이 데이터를 삭제할 수 있습니다. TTL을 통해 삭제되는 데이터는 해당 시점 이후 바로 삭제되는 것이 아닌 해당 시간 이후 천천히 삭제가 되는 구조이기 때문에 요구사항으로 인하여 바로 삭제가 되어야 하는 로직이 아닌 경우 TTL을 활용하여 비용 효율적으로 데이터를 삭제할 수 있습니다. 하지만 Amazon DynamoDB global tables에서 TTL을 사용할 경우 하나의 리전에서는 무료로 삭제가 되지만 N-1개의 다른 리전에 있는 데이터는 rWCU를 소모하여 삭제됩니다.

테이블 사전 프리워밍(Pre-warming)

프로비저닝된 용량 모드는 예측 가능한 애플리케이션 트래픽이 있고 Auto Scaling을 사용하여 트래픽 변화에 대응하여 용량을 조정하는 경우의 옵션입니다. 그러나 요청 비율이 프로비저닝된 용량을 초과하면 제한됩니다. 비용 효율성을 위해 프로비저닝된 용량을 100% 활용하여 작동을 하는것을 어려운 일 입니다. ReturnConsumedCapacity 매개변수를 사용하여 작업이 소비한 용량을 확인할 수 있습니다.

만약 요청 패턴이 예측할 수 없다는 점을 고려하면 온디맨드 용량 모드가 더 적합 합니다. 온디맨드 용량 모드로 새로 생성된 테이블은 최대 4,000개의 쓰기 요청 단위, 12,000개의 읽기 요청 단위 또는 이 둘의 조합을 처리할 수 있습니다. 온디맨드 용량 모드를 사용하면 요청이 테이블의 이전 최고치의 두 배까지 버스팅 될 수 있습니다. 하지만 온디맨드 용량 모드는 요청이 30분 이내에 이전 최고치의 두 배를 초과하면 제한이 발생할 수 있습니다. 트래픽 속도가 다르며 최고치 수준이 기존 용량 이전에 달성한 최대 요청수 보다 2배이상 높은 경우 프로비저닝된 용량 모드를 활용하여 테이블의 파티션 개수를 예상 트래픽 수준으로 미리 확보 할 수 있습니다.

테이블을 프리워밍 하려면 다음 단계를 따르세요.

  1. 계정 제한을 확인하고 프로비저닝 모드에서 원하는 용량에 도달할 수 있는지 확인하세요.
  2. 이미 존재하는 테이블이나 온디맨드 모드의 새 테이블을 사전 준비하는 경우 예상되는 최대 사용량이 발생하기 최소 24시간 전에 이 프로세스를 시작하세요. 24시간에 한 번만 온디맨드 모드와 프로비저닝 모드 간에 전환할 수 있습니다.
  3. 현재 온디맨드 모드인 테이블을 프리워밍 하려면 프로비저닝 모드로 전환하고 테이블이 활성화될 때까지 기다립니다. 그런 다음 다음 단계로 이동하십시오. 프로비저닝 모드에 있거나 이미 24시간 동안 프로비저닝 모드에 있었던 새 테이블을 미리 준비하려는 경우 기다리지 않고 다음 단계로 진행할 수 있습니다.
  4. 테이블의 쓰기나 읽기 처리량 중 하나를 원하는 최고 값으로 설정하고 활성화 상태까지 기다립니다. 온디맨드 방식으로 다시 전환할 때까지 프로비저닝된 높은 처리량으로 인한 비용이 발생합니다.
  5. 온디맨드 용량 모드로 전환합니다. 이때 테이블 안에 생성된 파티션의 개수를 변경되지 않습니다.

다음은 DynamoDB의 테이블 프리워밍 대한 영상입니다. DynamoDB 온디맨드 용량 모드를 사용하여 급증하는 워크로드를 수행하고 비용을 90% 이상 최적화한 내용을 설명하는 블로그처럼, 워크로드에 따라 개발/검증/스테이징 환경처럼 24시간 꾸준한 트래픽이 없다면 온디맨드 용량 모드가 비용 효율적이 될 수 있습니다.

워크로드에서 Scan API를 사용하는 경우

DynamoDB의 Scan 작업은 베이스 테이블 또는 보조 인덱스의 모든 항목을 읽어옵니다. 기본적으로 Scan 작업은 테이블이나 인덱스에 속한 항목의 데이터 속성을 모두 반환합니다. 하지만 Scan 작업에서 ProjectionExpression을 사용하면 모두가 아닌 일부 속성(Attribute)만 가져올 수 있고, FilterExpression을 사용하면 불필요한 아이템을 제거 후 반환받을 수 있습니다.

DynamoDB의 SCAN API는 일반적인 RDBMS와는 다르게 데이터를 읽을 때 최대 1MB 단위로 데이터를 읽게 됩니다. 때문에 대용량 테이블에서 OLTP 용도로 SCAN API를 사용할 수 없습니다. 일반적인 경우 SCAN은 한 테이블의 모든 아이템에 특정 속성을 추가할 때에 사용할 수 있습니다.
하지만 대부분의 워크로드에서 SCAN API를 활용하여 DynamoDB의 데이터를 읽어야 하는 경우, 애플리케이션이 Scan이 아닌 Query를 사용하도록 키 디자인을 해야 합니다. 베이스 테이블에서는 GetItemBatchGetItem API 사용도 사용할 수 있습니다.
그 밖에도 Scan 작업이 요청량에 미치는 영향을 최소화할 수 있도록 애플리케이션을 설계할 수 있습니다. 여기에는 Scan 작업 대신 글로벌 보조 인덱스를 사용하는 것이 더 효율적일 수 있는 경우의 모델링이 포함될 수 있습니다. 이 프로세스에 대한 자세한 내용은 이 영상에서 확인 가능 합니다.

DynamoDB global tables

만약 글로벌 서비스를 운영을 할 때에 리전별로 다른 테이블을 사용한다면 동일한 데이터에 대하여 업데이트 충돌 그리고 일관성 유지를 위한 작업이 동반이 되고 각종 유지보수 및 관리에 많은 개발자의 노력이 필요합니다. 개발자의 생산성은 제품의 개발 속도와 연관이 되기 때문에 매우 중요한 요소 입니다. 따라서 최소한의 유지보수와 문제상황이 발생한다면 개발자의 생산성이 향상될 수 있습니다.

DynamoDB global tables은 완전 관리형 서버리스, 다중 리전, 다중 활성 데이터베이스입니다. DynamoDB global tables을 사용하면 리전 간에 데이터를 복제하고 다중 활성 워크로드의 업데이트 충돌을 해결하는 어려운 작업을 없앨 수 있습니다. 데이터 정합성 및 충돌최종 쓰기 우선 적용(last writer wins) 방법을 사용합니다. 또한, 글로벌 테이블을 사용하면 전체 리전에서 드물게 격리 또는 성능 저하 문제가 있는 경우에도 애플리케이션의 가용성을 높게 유지할 수 있습니다. 이 기능을 활용하는 경우 리전별로 한개의 테이블로 작업할 수 있게 됩니다.

DynamoDB global tables을 활용하게 된다면 글로벌 서비스를 운영할 때의 많은 고려 요소들이 없어 질 수 있습니다. 전체 데이터 분석, 이를 활용한 다른 리전에서의 서비스 운영 등 글로벌 서비스를 운영할 수 있습니다. 이를 통해 개발자의 생산성을 높여 글로벌 서비스를 운영할 때의 제품 개발을 조금더 견고하고 비용 효율적으로 생산 할 수 있습니다.

DynamoDB Accelerator(DAX) 미지원 리전의 대응 방안

DynamoDB Accelerator(DAX)는 DynamoDB를 위해 구축된 고가용성의 완전관리형 읽기 전용 캐싱 서비스입니다. DAX는 초당 수백만 건의 요청 속도에서도 밀리초에서 마이크로초까지 최대 10배 향상된 성능을 제공합니다. DAX가 DynamoDB 테이블에 인 메모리 가속화를 추가하는데 필요한 모든 작업을 수행하므로 개발자가 캐시 무효화, 클러스터 관리 또는 데이터 집단을 관리할 필요가 없습니다. DAX는 하나의 클러스터에 읽기/쓰기가 가능한 하나의 프라이머리와 최대 10개의 읽기 전용 리더로 구성할 수 있고, 다양한 인스턴스 타입과 사이즈를 제공합니다.

일반적으로 DAX는 DynamoDB의 데이터 캐싱을 위해 활용 됩니다. 워크로드에 데이터가 캐시 히트율이 낮은 경우 캐시에 있는 데이터를 잘 활용하지 못합니다. 이런 워크로드에서는 일반적인 DynamoDB만을 활용하여도 충분한 성능으로 서비스에 활용할 수 있습니다.

특히 글로벌 서비스 구축 시 사용하는 리전에 따라 DAX는 지원될 수도 아닐 수도 있습니다. 하나의 DAX 클러스터가 제공하는 것보다 캐시 데이터가 많거나 처리 트래픽이 많은 경우, 혹은 개발자 생산성을 위해 모든 리전에서 공통 캐시 레이어가 필요할 경우 Amazon ElastiCache를 활용할 수 있습니다. ElastiCache는 Redis 및 Memcached와 호환 캐싱 서비스로 현대적 애플리케이션의 성능을 최적의 비용으로 실시간으로 개선해줍니다. ElastiCache는 마이크로초의 응답 시간으로 초당 수억 개의 작업으로 확장되며 엔터프라이즈급 보안 및 신뢰성을 제공합니다. 또한, re:Invent 2023에서는 마이너 버전 패치에서 해방될 수 있는 ElastiCache Serverless도 발표되었습니다.

서비스 오픈 전략

위에서 설명한 여러가지 DyanmoDB 체크포인트를 활용하여 다양한 서비스 오픈 전략을 활용할 수 있습니다.

첫 번째로 서비스 할당량을 필요한 만큼 증설 후 프로비저닝된 용량 모드를 통하여 서비스 오픈 전 테이블 프리워밍을 수행합니다. 처음 서비스가 오픈 되었을때는 트래픽 예측이 어렵기 때문에, 이후 서비스의 트래픽이 어느정도 패턴을 보일 때 까지 온디맨드 용량 모드를 활용하여 서비스를 오픈 할 수 있습니다. 온디맨드 용량 모드를 활용하면 서비스를 오픈 했을때에 예측하지 못한 트래픽 상황에서도 이전 피크의 2배까지 트래픽을 즉시 처리할 수 있게 됩니다. 이를 통하여 서비스 초반에 안정적으로 운영할 수 있습니다.

두 번째로 서비스 오픈 몇일 후 트래픽의 패턴이 보이기 시작한다면 약간의 오버 프로비저닝을 하더라도 프로비저닝된 용량 모드로 변경하고 Auto scaling 적용하여 비용을 가변적으로 만듭니다. 이를 통하여 특정 패턴에 따라 자동으로 유동적인 처리량을 가지고 서비스를 운영할 수 있습니다. 만약 트래픽 패턴이 스파이크가 있는 특성을 갖게 된다면 Auto Scaling의 Target utilization을 더 낮은 값을 설정하여 버스트 기능을 충분히 활용 할 수 있게 합니다. 혹은 특정 시간에 주기적인 벌크 작업이 필요하다면 Auto Scaling에 스케줄링을 설정할 수 있습니다.

마지막으로 프로비저닝된 용량 모드로 변경을 하였다면 예약 용량을 구매 해야 합니다. 구매 시엔 전체 비용 중 예약 용량이 처리되는 수치의 비용 목표를 설정합니다. 이후 매달 목표를 맞출 수 있도록 민첩하게 예약 용량의 추가 구매 여부를 결정하여 비용 효율적으로 DynamoDB를 사용할 수 있도록 합니다.

결론

이 글은 DynamoDB를 사용하여 서비스를 오픈 하기 전 체크포인트와 오픈 전략을 다룹니다. DynamoDB를 활용하여 서비스를 오픈 할 때 빠른 확장을 위한 안정적인 환경을 구성하고 안정적으로 대량의 트래픽을 처리 가능한 환경을 구축할 수 있습니다. 사전 체크포인트와 오픈 전략을 통하여 서비스 오픈 초기 예상 이상의 트래픽을 처리할 수 있는 환경을 구축 할 수 있습니다. 서비스 오픈 전 꼭 체크포인트와 서비스 오픈 전략을 확인하여 안정적이고 대량 트래픽 처리를 할 수 있는 환경으로 안정적으로 서비스를 운영해 보시길 바랍니다.

Daeheon Oh

Daeheon Oh

오대헌 테크니컬 어카운트 매니저는 데이터베이스에 대한 경험을 바탕으로 Enterprise support 고객에게 데이터베이스를 안정적으로 서비스 될 수 있도록 고객과 함께 효율적인 아키텍처와 운영 방식을 구성하는 역할을 수행하고 있습니다.

Hyuk Lee

Hyuk Lee

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