조정 용량을 통해 DynamoDB에서 균일하지 않은 데이터 액세스 패턴을 수용하는 방법
Amazon DynamoDB는 모든 규모에서 높은 성능을 제공하는 비관계형 데이터베이스입니다. 처리량에 대한 요구 사항에 맞게 조정되는 완전관리형 서비스이며 보안, 백업 및 데이터 보호 기능이 기본적으로 포함되어 있습니다. 100,000명이 넘는 개발자가 데이터 액세스 지연 시간이 짧아야 하는 모바일, 웹, 게이밍, 광고 기술, IoT 및 기타 애플리케이션의 개발에 DynamoDB를 활용해왔습니다.
그러나, 용량 부족 관련 오류를 해결하기 위해 추가 용량을 프로비저닝해야 했던 고객들로부터 요청 실패에 대한 우려를 듣곤 합니다. 이러한 고객들은 일부 키를 다른 키보다 더 많이 읽고 쓰는 쿼리 패턴처럼 기본 키(해시 키 또는 파티션 키라고도 함) 전체에서 트래픽이 균일하지 않은 워크로드에 DynamoDB를 사용하기가 까다롭다고 생각합니다.
이 게시물에서는 왜 DynamoDB의 용량 및 프로비저닝을 더 이상 걱정하지 않아도 되는지에 대해 설명합니다. 먼저 DynamoDB가 파티션 및 서버에 데이터를 분할하는 방법에 대한 기본 정보를 다룬 후, 과거에 경험했을 수 있는 균일하지 않은 워크로드 문제를 수정하는 조정 용량이라는 기능에 대해 중점적으로 설명합니다. 마지막으로는 자체 AWS 계정에서 실행할 수 있는 예제 애플리케이션을 통해 조정 용량의 실제 작동 과정을 살펴봅니다.
DynamoDB의 조정 방식
참고: DynamoDB 파티셔닝에 대해 이미 잘 알고 있고 조정 용량에 대한 내용을 알고 싶다면 다음 섹션으로 건너뛰어도 됩니다.
먼저, DynamoDB의 데이터 관리 방법을 설명하도록 하겠습니다. 다른 비관계형 데이터베이스처럼 DynamoDB는 테이블을 여러 서버에 있는 하나 이상의 파티션에 수평적으로 분할합니다. 그렇다면 DynamoDB를 사용하는 것과 자체 NoSQL 데이터베이스를 호스팅하는 것은 어떻게 다를까요? Amazon EC2가 서버 하드웨어를 가상화하여 확장성, 효율성 및 경제성의 이점이 있는 다중 테넌트 환경을 생성하듯이 DynamoDB도 데이터베이스 하드웨어를 사용해 같은 작업을 수행합니다.
DynamoDB는 다음 예제 다이어그램에 나와 있는 것처럼 테이블 파티션을 물리적 서버 전체에 투명하게 분할합니다. Table1은 서로 다른 서버에 위치한 파티션 2개(T1.p1 및 T1.p2)에 분할됩니다.
DynamoDB를 시작하려면 테이블을 생성하고 테이블로 읽기 및 쓰기 작업을 보내기만 하면 됩니다. 데이터베이스 노드 또는 클러스터에 적합한 하드웨어(예: CPU, RAM 및 스토리지)를 선택하느라 고민하지 않아도 됩니다. DynamoDB가 하드웨어 리소스를 자동으로 처리하기 때문입니다. 애플리케이션의 요청 속도를 처리하기에 적절한 읽기 및 쓰기 처리량은 DynamoDB 자동 조정을 통해 자동으로 설정됩니다. 워크로드가 변경되면 DynamoDB가 읽기 처리량, 쓰기 처리량 및 스토리지의 변경에 대응하여 파티션을 자동으로 분할하고 동적으로 재분배합니다.
DynamoDB 재분할의 작동 방식에 대한 예를 살펴보겠습니다. 이 예에서 재분할은 스토리지 증가에 의해 트리거되었습니다. 단일 DynamoDB 테이블이 파티션 A, B 및 C에 분할되어 있다고 가정해 보십시오. 이러한 파티션은 다음 그림에 나와 있는 것처럼 3개의 개별 물리적 서버(Server 1, Server 2 및 Server 3)에 저장됩니다.
참고: 실제로 DynamoDB는 이 테이블의 데이터를 9개의 SSD(Solid-Sstate Drive)(3개가 아님)에 저장합니다. 서버 장애 또는 가용 영역 중단 시 내결함성을 제공하기 위해 AWS 리전의 3개 시설에 자동으로 데이터가 복제되기 때문입니다. 그러나 이 예에서는 간단한 설명을 위해 복제를 생략했습니다.
이 예에서 애플리케이션은 대부분의 쓰기를 파티션 A에 수행하므로 파티션 A의 스토리지는 다음 그림에서 볼 수 있듯이 거의 가득 찬 상태입니다.
DynamoDB는 사용자 입력 없이 파티션 A를 Server 1에 유지되는 파티션 A와 Server 4에 유지되는 파티션 D의 두 부분으로 자동으로 분할합니다. 이 변경은 애플리케이션에 미치는 영향 없이 투명하게 수행되며 DynamoDB는 새 파티션으로 자동으로 요청을 전송합니다.
이제 파티션의 작동 방식에 대해 설명했으니 DynamoDB의 조정 용량에 대해 자세히 살펴보도록 하겠습니다.
조정 용량의 작동 방식
DynamoDB를 사용한 경험이 있다면 DynamoDB의 권장 사항에 대해 알고 계실 것입니다. 즉, 최적의 성능을 위해서는 고르게 분산된 트래픽을 전송하도록 애플리케이션을 구축하는 것이 좋습니다. 다시 말해 기본 키 전체에 요청이 고르게 분산되어야 합니다. 조정 용량 기능이 제공되기 전에 DynamoDB는 읽기 및 쓰기 처리량을 파티션 전체에 고르게 할당했기 때문입니다. 예를 들어 초당 400건의 쓰기(400WCU 또는 쓰기 용량 단위)를 처리할 수 있는 테이블이 4개 파티션에 분산되어 있는 경우 각 파티션에는 100WCU가 할당됩니다. 균일하지 않은 워크로드로 인해 한 파티션에서 초당 100건이 넘는 쓰기를 수신하면(핫 파티션) 이러한 요청에서 ProvisionedThroughputExceededException
오류가 반환될 수 있습니다.
실제로 완벽하게 균일한 액세스를 달성하기는 어렵습니다. DynamoDB 조정 용량은 전체 테이블 레벨 처리량이 초과되지 않는 한 핫 파티션에 대한 애플리케이션의 읽기 및 쓰기 요청을 요청 실패 없이 계속해서 처리하여 균일하지 않은 데이터 액세스 패턴을 수용합니다. 조정 용량은 더 많은 트래픽을 수신하는 파티션의 처리 용량을 자동으로 늘리는 방식으로 작동합니다. 조정 용량에 대한 심층 정보는 AWS re:Invent 2017 브레이크아웃 세션 동영상(63분)을 참조하십시오.
다음 다이어그램은 조정 용량의 예를 보여줍니다. 이 예제 테이블은 4개 파티션에 고르게 분할되어 각 파티션에서 최대 100건의 초당 쓰기 용량을 유지할 수 있는 400WCU로 프로비저닝되었습니다. 그러나 애플리케이션에서 균일하지 않은 트래픽이 발생하여 파티션 4에서 초당 150건의 쓰기 요청을 수신하고 파티션 1~3에서는 초당 50건의 쓰기 요청만 수신합니다. DynamoDB 조정 용량은 파티션 4에 자동으로 “부스트”를 적용하여 할당된 100WCU보다 많은 용량을 소비할 수 있도록 합니다. 따라서 애플리케이션은 트래픽이 균일하지 않아도 계속해서 정상적으로 무기한 작동합니다.
조정 용량은 모든 DynamoDB 테이블에서 기본적으로 사용할 수 있으므로 명시적으로 활성화하거나 비활성화하지 않아도 됩니다. DynamoDB에 의해 완벽히 관리되므로 새로운 Amazon CloudWatch 지표를 모니터링할 필요가 없습니다. DynamoDB가 테이블에 조정 용량 기능을 활성화하면 워크로드가 균형을 잃더라도 테이블이 불균형 상태의 트래픽을 무기한 처리합니다.
캐나다의 인구 조사 애플리케이션 – 조정 용량 기능의 작동 방식
균일하지 않은 워크로드를 생성하는 일반적인 애플리케이션에 대응하여 핫 파티션에서 생성되는 ProvisionedThroughputExceededException
오류를 없애는 조정 용량 기능의 작동 방식을 살펴보겠습니다. 이 섹션에서는 직접 다운로드해 실행할 수 있는 예제 애플리케이션의 결과를 설명합니다.
시나리오 – 캐나다 인구 조사
10개의 주와 3개의 준주에 걸쳐 있는 캐나다의 인구에 대한 온라인 인구 조사 애플리케이션을 구축한다고 가정합시다. DynamoDB를 사용하고, 다음 이미지의 키 스키마(Province
는 파티션 키이고 ResponseId
는 정렬 키임)가 포함된 테이블에 애플리케이션의 사용자 응답을 저장하도록 선택합니다.
이제 캐나다에 대한 구체적인 지식이 없는 것으로 가정하겠습니다. 특히 다음 이미지에 표시된 캐나다의 인구 분포에 대해 전혀 모르는 것으로 가정합니다.
주 전체에 인구가 고르게 분산되어 있지 않기 때문에 파티션 키와 정렬 키의 스키마 선택이 적합하지 않다는 것을 알 수 있습니다. 즉, 인구가 더 많은 주에서는 쓰기 요청이 더 자주 발생하므로 DynamoDB 액세스 패턴은 균일하지 않은 트래픽이 배포되는 양상을 가지게 될 것입니다. 캐나다 인구에 대한 다음 원형 차트를 보면 캐나다 인구의 60% 이상이 온타리오와 퀘벡의 2개 주에 거주하는 것을 알 수 있습니다.
예제 인구 조사 애플리케이션의 개요
예제 애플리케이션은 캐나다 인구 조사를 위한 웹 애플리케이션을 시뮬레이션합니다. 이 애플리케이션은 3,000WCU 및 3,000RCU(읽기 용량 단위)를 제공하고 기본 키가 Province
이며 정렬 키가 ResponseId
인 DynamoDB 테이블을 생성합니다. 이 만큼의 처리 용량을 프로비저닝하면 파티션 4개가 생성됩니다. 이후에 쓰기 처리 용량을 100WCU로 낮추면 각 4개 파티션에 25WCU가 할당됩니다. 이제 애플리케이션은 캐나다의 실제 인구 분포에 따라 최종 사용자로부터 초당 70건의 속도로 인구 조사 회신을 수신합니다. 인구 조사 회신이 수신될 때마다 예제 애플리케이션에서 생성된 DynamoDB 테이블에 새 항목이 기록됩니다. 애플리케이션은 각각의 주마다 성공한 쓰기 작업의 수를 나타내는 데이터 행을 10초 간격으로 생성합니다.
예제 애플리케이션을 직접 실행하려면 이 GitHub 리포지토리로 이동하십시오. 애플리케이션을 실행하기 전에 다음을 숙지하시기 바랍니다.
- 애플리케이션을 실행하려면 AWS 계정과 DynamoDB 액세스 권한이 있어야 합니다.
- 시뮬레이션을 실행하는 시간과 월별 프리 티어 리소스의 소진 여부에 따라 작은 금액의 DynamoDB 요금(약 10 USD)이 발생할 수 있습니다. 애플리케이션에는 약 4시간 동안 3,000WCU 및 3,000RCU가 필요합니다.
- 시뮬레이션이 완료된 후 정리하려면 애플리케이션에 사용된 DynamoDB 테이블을 축소하거나 삭제해야 합니다.
예제 애플리케이션 실행 및 결과 해석
애플리케이션을 실행해 실제 인구 분포에 따라 주 전체에 초당 70건의 쓰기를 임의로 실행할 때 각 주에 발생하는 트래픽을 확인해 보겠습니다. 다음 그래프는 출력의 구성을 보여줍니다. 파란색 ON
선(온타리오)과 주황색 QC
선(퀘벡)의 성공 비율이 감소한 후 정상으로 회복됩니다.
온타리오주와 퀘벡주에 대한 쓰기 성공 비율은 약 13분 후에 감소했습니다. 온타리오주와 퀘벡주의 문자열 값이 임의 선택에 의해 동일한 파티션으로 매핑되었기 때문입니다. 그 결과 처리량의 25%만 프로비저닝된 한 파티션에서 60%가 넘는 테이블 트래픽을 처리해야 했습니다. 기본적인 5분 버스트 용량(성공 비율이 즉시 감소하지 않은 이유)은 도움이 되기는 했지만 트래픽 불균형이 지속되면서 결국 소진되었습니다. 조정 용량이 제공되기 전에 이러한 ProvisionedThroughputExceededException
오류의 유일한 해결책은 프로비저닝된 처리량을 늘리거나 애플리케이션을 다시 설계하여 데이터 액세스를 균일하게 만드는 것 뿐이었습니다.
그러나 다음 차트를 보면 조정 용량이 활성화되는 약 30분 후에 쓰기 성공 비율이 회복되는 것을 알 수 있습니다. DynamoDB는 파티션 레벨의 처리량 부족으로 야기된 요청 실패를 자동으로 탐지했습니다. 그런 다음 DynamoDB는 불균형을 효과적으로 처리하기 위해 테이블을 조정했습니다. 테이블에서 요청 실패가 발생한 후 조정 용량을 통해 정상 성능이 복원되기까지 소요되는 시간은 일반적으로 5~30분입니다.
다음 CloudWatch 그래프에서 자세한 내용을 볼 수 있습니다. 이 그래프는 성공한 쓰기 요청(파란색 선)과 스로틀된 쓰기 요청(주황색 선)을 보여줍니다. 이 그래프에서도 동일한 패턴이 나타납니다. 워크로드가 정상적으로 실행되고, 파티션 레벨 활동의 부족으로 인한 스로틀이 발생한 후, 조정 용량 기능에 의해 정상 성능이 복원됩니다.
결론
이 블로그 게시물이 조정 용량을 통해 DynamoDB에서 불균형 상태의 워크로드를 수용하는 방법을 이해하는 데 도움이 되었길 바랍니다. 조정 용량 기능은 읽기 및 쓰기 처리량의 오버프로비저닝을 방지합니다. 자동 조정 기능과 함께 사용하면 처리량을 필요에 따라 프로비저닝하고, 트래픽이 감소하면 축소할 수 있습니다.
DynamoDB 조정 용량에 대한 자세한 내용은 DynamoDB 조정 용량 이해와 이 AWS re:Invent 2017 브레이크아웃 세션 동영상(63분)을 참조하십시오.