AWS 기술 블로그

Amazon DynamoDB를 사용한 비용 효율적인 대량 처리

글은 AWS Database Delivery Blog게시된 Cost-effective bulk processing with Amazon DynamoDB by Jason Hunter한국어 번역 편집하였습니다.

Amazon DynamoDB 테이블은 수백만, 수십억 또는 수조 개의 항목 (Item) 들을 저장할 수 있습니다. 사이즈가 큰 테이블의 항목에 대해 대량 업데이트 작업을 수행해야 하는 경우, 비용을 고려하는 것은 매우 중요합니다. 이 게시물에서는 DynamoDB사용에 있어 비용 효율적인 인플레이스 (in-place) 대량 처리를 위한 세 가지 기술을 보여줍니다.

대량 처리의 특징 

대량 처리를 하는 데에는 아래와 같이 여러 가지 이유가 있을 수 있습니다:

  • 컴플라이언스 준수를 위해 오래된 항목을 삭제하거나 지속적인 스토리지 비용을 절약을 위해서 일 수 있습니다. DynamoDB TTL(Time to Live)은 이와 같은 사용 사례를 대상으로 하는 무료 (zero-cost) 삭제 기능을 제공합니다. 다만 삭제를 대상으로 하는 모든 개별 항목에 TTL 속성이 미리 설정되어 있어야 합니다. 오래된 항목들은 TTL 속성 없이 이미 로드되었을 수 있습니다.
  • 적절한 시기에 자동으로 항목들이 삭제되도록, 최신 생성되는 항목에 TTL 속성값을 채우기 위해서 일 수도 있습니다.
  • 새로운 Global Secondary Index(GSI) 파티션 키 또는 정렬 키를 net-new 속성으로 대체하여 채우기 위해서 일 수 있습니다. 예를 들어 GSI sort key가 주(state)와 도시(city) 즉, (<state>#<city>)의 조합이어야 하는 경우 모든 항목에 새 속성을 배치해야 합니다.
  • 즉시 완료할 필요가 없는대량 변경 작업을 수행하기 위해서 일 수도 있습니다.

대량 처리의 일반적인 특징은 바로 처리할 필요가 없다는 것입니다. 종종 대량 요청은 몇 초 후, 몇 시간 후 혹은 다음 날로 늦춰 진행하여도 문제가 없습니다. 이것은 모든 작업을 즉시 수행해야 하는 경우보다 저렴한 비용으로 작업을 수행시키는 혁신적인 설계를 가능하게 합니다.

대규모 처리 과금 예시

총 테이블 크기가 250TB이고 각 항목의 크기가 500바이트인 5천억 개의 항목이 있는 매우 큰 테이블이 있다고 가정해 보겠습니다. 이 데이터는 지난 36개월 동안 누적되었으며, 이제 13개월보다 오래된 타임스탬프 속성이 있는 모든 항목을 삭제하려고 합니다. 삭제해야 하는 항목은 3,190억 개입니다. 또한 앞으로 13개월이 지나면 자동으로 삭제되도록 다른 1,810억 개의 항목에 TTL 속성을 추가한다고 상상해 보겠습니다.

Metric Quantity
Item count 500 billion
Item size 500 bytes
Table size 250 TB
Items to delete 319 billion
Items to update 181 billion

온디맨드 모드를 사용하는 모든 항목을 수정하는 비용

5,000억 개의 작은 항목들을 작성하는 비용(삭제 또는 업데이트도 이에 해당)은 테이블 모드에 따라 다릅니다. 온디맨드 모드에서는 정확히 5,000억 WRU(Write Request Unit)가 필요합니다. 요청 타이밍을 제어하는 것에 있어 온디맨드 사용은 이점이 없습니다(핫 파티션을 피하기 위해 작업을 테이블 전체에 분산시키는 경우 제외). 다음은 온디맨드 모드의 테이블에 대한 us-east-1 AWS 리전에 대한 비용 계산 분석 방법입니다.

백만 개당 $1.25일 때 5000억 WRUs의 가격 = $625,000

또한 읽기 비용도 고려할 필요가 있습니다. 한 번의 Scan은 한 번에 여러 항목을 가져올 수 있습니다. 최종적 일관된 읽기(consistent reads)를 사용하면 Consumed Read Unit 당 16개의 500바이트 항목을 가져올 수 있습니다. 즉, 5,000억 개의 항목을 모두 스캔하려면 약 312억 5,000만 RRUs(Read Request Units)가 필요하게 됩니다.

백만 개당 $0.25일 때 312억 5천만 개 RRUs의 가격 = $7,810

읽기 비용은 쓰기 비용에 비해서는 덜 중요하므로, 이 게시물에서는 최적화된 쓰기 타이밍에 중점을 두겠습니다.

Action Quantity needed Cost per Total cost
Write 500 billion
500-byte items
500 billion WRUs $1.25 per million $625,000
Scan 500 billion
500-byte items
31.25 billon RRUs $0.25 per million $7,810

비용 1달러로 약 790,000개의 항목을 업데이트할 수 있습니다. 변동이 없고 예측가능한 워크로드이므로, 프로비저닝 모드를 사용하면 훨씬 더 효과적일 수 있습니다.

프로비저닝 모드를 사용하는 모든 항목을 수정하는 비용

프로비저닝 모드에서는 가격 계산이 좀 더 복잡합니다. 이는 대량 쓰기와 오가닉 쓰기라는 두 가지의 쓰기 작업이 테이블에 쓰로틀링을 걸지 않는 방향에서 서로 공존해야 하기 때문입니다. 이 게시물의 뒷부분에서 확인할 수 있듯이, 비용 절감 효과는 서로 공존하는 관계에서 찾을 수 있습니다.

오가닉 트래픽을 처리하는 프로비저닝 된 테이블은 일반적으로 오토 스케일링 기능이 활성화되어 있는 경향이 있습니다. 오토 스케일링은 프로비저닝 시키는 리소스의 양을 소비되는 리소스의 양보다 매우 높은 값으로 유지함으로써, 일시적인 트래픽 급증이 프로비저닝 된 리소스 내에서 처리되도록 하는 것을 목표로 합니다. 이를 위해 오토 스케일링은 소비량에 대응하여 프로비저닝할 리소스의 양을 제어합니다.

오토 스케일링 설정에는 최솟값(이 값 미만으로 조정 안 함), 최댓값(이 값 이상으로 조정 안 함) 및 목표 사용률(Target Utilization, 디폴트로 70% 값으로 세팅되며, 프로비저닝 된 양과 동일하게 소비하는 것을 목표로 함)이 포함됩니다. 목표 사용률은 프로비저닝 된 양을 결정하기 위해 사용된 양을 초과하는 예비분을 효과적으로 제어합니다. 숫자가 높을수록 예비분이 적게 제공됩니다 (쓰로틀링 위험 증가).

1,000,000 WCU를 소비하는 지속적인 대량 작업은 500,000초(139시간) 동안 실행되어 5,000억 개의 항목을 모두 처리합니다. 이 시간 동안 오토 스케일링은 증가된 트래픽을 감지하고 오가닉 트래픽에 필요한 모든 것 외에 추가로 1,428,500 WCU(1,000,000 WCU를 70% 목표로 나눈 값)를 프로비저닝 합니다.

프로비저닝 된 용량 모드의 테이블에 대한 비용 계산은 us-east-1에서 다음과 같이 표시됩니다.

1,428,500 WCUs * 139 시간 * WCU-시간당  $0.00065 = $129,065

상대적으로 적은 스캔 비용이 다음 표에 포함되어 있습니다.

Action Quantity consumed Quantity provisioned Cost per Total cost
Write 500 billion
500-byte items
500 billion WRUs1,000,000 WCUs
for 139 hours
1,428,500 WCUs for
for 139 hours
$0.00065 per
WCU-hour
$129,065
Scan 500 billion
500-byte items
62,500 RRUs for 139 hours 89,285 RCUs for
for 139 hours
$0.00013 per RCU-hour $1,614

위 표는 비용 1달러당 업데이트되는 약 3,826,000개의 항목에 대한 정보입니다. 이를 통해 온디맨드 모드에 대해 즉각적인 대응이 필요하지 않은 워크로드에서 예상할 수 있는 온디맨드 모드를 통한 상당한 비용 절감을 확인할 수 있습니다. 위의 표에서 볼 수 있듯이, 온디맨드 모드는 트래픽이 급증하는 경우 실제로 비용이 더 낮을 수 있지만, 프로비저닝 된 경우에는 완벽하게 균일한 작업 가격이 표시됩니다.

이제 무료 또는 저렴한 인플레이스(in-place) 업데이트를 달성하기 위해 대량 쓰기 작업이 수행되는 시기와 속도를 제어하는 세 가지 타이밍의 기술을 살펴보겠습니다.

사용하지 않은 예약 용량(Reserved Capacity) 이용하기

예약 용량(Reserved Capacity, RC)을 구매한 경우, 사용하지 않은 예약 용량이 있는 기간 동안에는, 이를 무료로 대량 쓰기를 하는 시간으로 지정하여 활용할 수 있습니다.

예약 용량은 최소 쓰루풋을 프로비저닝 하는 것에 대해 1년 또는 3년짜리 약정 할인을 제공합니다. 일일 트래픽이 300,000 WCU에서 700,000 WCU까지 다양할 경우, 구매할 1년의 RC의 적절한 양은 약 500,000 WCU입니다. 최저점에서만 구매하면, 기준선 이상의 모든 작업 부하에 대한 절감 효과를 놓치게 됩니다. 따라서 하루 중 대부분의 최고 초과 공급량의 값으로 구매하는 것이 좋습니다. 한편 중간 지점에서 구매하는 것이 가장 좋은 경향도 있습니다.

이것은 다시 말해, 오가닉 트래픽이 300,000에서 500,000 사이일 때 언제든지 정교하게 구성된 벌크 잡 익스큐터(bulk job executor)가 그 간격을 메우고 추가 비용 없이 대량 작업을 수행할 수 있음을 의미합니다. 만약 최소 500,000 트래픽을 사용할 것이라면, 데이터 작업량이 적어지는 구간을 대량 작업으로 채우는 것이 좋습니다.

다음 차트는 이를 시각화한 것입니다. 뾰족한 주황색 선은 하루 종일 위아래로 변동하는 오가닉 소비 용량입니다. 빨간색 가로선이 RC 구매 금액입니다. 수평의 구매한 라인 아래와 뾰족한 주황색 소비 라인 위의 차이가 무료 쓰기가 가능한 구간 입니다.

Figure 1: 사용되지 않은 예약 용량이 있는 기간과 일치하도록 시간 쓰기

과거 소비 표준 패턴에 따라 하루 중 특정 시간 동안 일정량의 자체 조절 용량을 소비하도록 매개변수화된 벌크 익스큐터(bulk executor)가 있다고 가정해 보겠습니다. 예를 들어 일반적으로 한밤중의 시간에 사용되도록 예약되었지만 결국은 미사용 된 WCU가 200,000개 있는 경우, 벌크 익스큐터는 해당 WCU를 자체적으로 소비해 버린다는 것 알 수 있습니다. 초당 200,000개의 항목을 처리하는 속도로 처리하면 694시간 안에 5,000억 개의 항목이 모두 처리됩니다. 이 수준의 미사용 RC로 주당 평균 30시간 동안 처리한다고 가정하면, 백로그를 처리하는 데 13주가 소요됩니다.

테이블이 하나만 있지만 대규모 조직에서는 추가 작업이 필요한 경우, 과거 표준을 계산하는 것은 비교적 간단합니다. 예약 용량은 단일 테이블에만 할당되지 않고, 같은 지불 계정(Payer Account)에 연결되어 있는 모든 연결 계정(Linked Account)의 특정 리전에 대한 모든 테이블에서 공유되기 때문입니다. 한 테이블에서 사용량이 적은 기간만 중요한 것이 아니라, 모든 테이블에서의 그 기간이 중요하며, 해당 기간 동안 사용되지 않은 RC를 계산하는 것에도 초점을 맞춰야 합니다. 이것이 바로 벌크 익스큐터에게 제공되는 실행 속도이기 때문입니다.

오토 스케일링으로 인해 이 디자인이 복잡해진 것은 사실입니다. 오토 스케일링의 기본 목표치를 70%로 두면, 실제로는 140,000개의 WCU만 사용할 수 있습니다. 이는 사용률 격차를 메우기 위해 200,000개의 예비 WCU가 모두 프로비저닝 되는 쓰기 수준이기 때문입니다.

그러면 이제 대량 처리 시간 동안 오토 스케일링 설정을 가장 공격적인 값인 90%로 올려 세팅할 수 있습니다. 이렇게 하면 예비분이 크게 줄어들고 최대 180,000개의 WCU를 소비하여 프로비저닝 된 200,000개의 WCU에 도달할 수 있습니다.

일반적으로 공격적인 목표 사용률을 설정하면 오가닉 트래픽 급증 중에 쓰로틀링에 걸릴 위험이 높아집니다. 벌크 익스큐터가  ProvisionedThroughputExceededException 를 수신할 때, 그 자신은 오가닉 트래픽 처리를 위한 사용량을 마련할 목적으로, 매우 신속하게 엄격한 자체 쓰로틀링을 걸어 잠시 동안 자체 처리량 소비를 중지함으로써 쓰로틀링의 위험을 완화할 수 있습니다. 예비분을 마련하는 것은 그것이 벌크 익스큐터의 작업에 의해 필요에 따라 소비됨으로써 여전히 효과적이라고 할 수 있습니다. 만일 대량 작업이 소비량을 빠르게 줄일 수 있다면, 예비분을 보수적으로 오토 스케일링할 필요가 줄어듭니다. 엄격한 자체 쓰로틀링 기능을 구현할 때, 의도치 않게 발생할 수 있는 자동 재시도를 방지하려면 SDK 재시도 설정을 조정해야 하는 것을 잊지 말아야 합니다.

이러한 접근 방식은 추가 서비스 비용 없이 시간이 지남에 따라 모든 업데이트를 수행하는 것이 가능하지만, 사전에 충분한 시간과 노력을 기울이는 엔지니어링 작업은 반드시 필요합니다.

오토스케일링의 사용률 타이트하게 사용하기

만약에 사용하지 않는 예약용량(Reserved Capacity)이 없지만 오토 스케일링이 포함된 프로비저닝 모드를 사용한다면, “오토 스케일링의 사용률 타이트하게 사용하기”를 통해서 거의 무료로 대량 쓰기를 수행할 수 있는 방법이 있습니다.

이전 세션의 마지막 부분에서 설명한 것과 같이, 오토 스케일링의 타겟 사용량의 목표는 짧은 시간 동안 버스트가 발생했을 때도 소비된 용량 보다 프로비전 한 양이 많도록 유지하는 것입니다. 높은 목표 사용률(Target utilization)은 예비 용랑을 낮게 하고, 반면에 낮은 목표 사용량은 많은 예비 용량을 발생하게 합니다. 아래 그림은 오토 스케일링이 어떻게 동작하는지 보여 줍니다. 뾰족한 주황색 선은 사용된 WCU이고 파란색의 수평한 선은 프로비저닝 된 WCU입니다.

Figure 2: 오토 스케일링으로 프로비전 된 WCU와 사용된(Consumed) WCU

이 방법은 우선 목표를 높입니다(즉 수평한 프로비전 라인을 낮춥니다). 그리고 오가닉 트래픽 위에 일정한 비율로 대량 작업을 추가합니다(스파이크 라인을 약간 높이고 프로비저닝 라인을 원래 위치로 되돌립니다). 만약 테이블 레벨에서 쓰로틀링이 발생한다면 대량 작업을 자체적으로 쓰로틀 할 수 있도록 합니다(이를 통해서 공격적인 목표 사용률을 설정하는 것을 가능하게 해 줍니다). 대량 작업은 추가 비용 없이 오가닉 트래픽의 일정 비율에 비례하는 속도로 수행됩니다.

다음 차트는 이를 시각화한 것입니다. 아래쪽 주황색 스파이크 한 선은 동일한 오가닉 트래픽을 나타내고, 파란색 평행한 선은 프로비저닝 된 양과 동일하며, 위쪽 뾰족한(spiky) 주황색 선(약간 더 진한)은 약간의 벌크 작업이 더해진 소비 용량을 나타냅니다. 목표 사용률을 높이게 되면 갑작스럽게 증가하는(스파이크한) 요청에도 프로비저닝 선 안에 유지하게 됩니다.

Figure 3: 오토스케일링의 사용률을 타이트하게 하고 쓰로틀이 잘 되는 대량 작업을 추가

목표 사용률이 높을수록 스파이크한 트래픽을 감당할 수 있는 여유가 적어지게 됩니다. 그렇기 때문에 당연히 안전한 수준보다 높게 타겟을 설정하지 않습니다. 처리량 초과 예외가 발생하면 대량 작업이 자체적으로 강하게 쓰로틀을 적용하여 오가닉 트래픽이 즉시 처리량을 확보할 수 있게 해 줍니다. 이를 통해서 스파이크한 오가닉 트래픽이 발생하여도 오렌지 선과 파란색 선 사이의 거리만큼의 리소스를 사용할 수 있기 때문에 매우 높은 설정 값도 적용이 가능합니다.

벌크 익스큐터는 모니터링된 오가닉 트래픽의 양의 일정한 비율을 사용하면서 운영 됩니다. 이는 목표 사용률이 높게 하면서 발생하는 차이를 활용 합니다. 타겟을 70% 에서 80% 로 변경하게 되면 벌크 작업이 시작됩니다. 이 벌크 작업은 오가닉 트래픽 사용량이 증가하던 감소하던 오가닉 트래픽의 약 15% 를 소비하게 됩니다. 수학적 계산을 통해서 프로비전된 라인은 사용률을 올리기 전에 소비된 것과 같은 수준으로 유지합니다.

70% 에서 80% 로 변경하면 15% 증가가 가능하다는 것은 아래 수식으로 확인이 가능합니다.

  • 500,000 WCU의 변동이 심한 오가닉 트래픽이 있다고 가정해 보겠습니다.
  • 목표가 70% 라면 오토 스케일링을 통해 500,000/0.7 = 714,285개의 WCU가 프로비저닝 됩니다.
  • 목표치를 80% 로 변경하면 500,000/0.8 = 625,000 WCU가 됩니다.
  • 500,000 건을 575,000건으로 변경하는 대량 작업의 15% 를 더하면 이제 575,000/0.8 = 718,750개의 WCU가 프로비저닝 되었습니다. 이것이 바로 우리가 시작한 곳입니다.

정확한 계산은 (80/70) – 1 = 14.3%입니다. 50% 목표를 최대 70% 까지 조정하는 경우 (70/50) – 1 = 40% 의 벌크 작업을 추가할 수 있습니다.

오가닉 트래픽 사용률의 변동폭이 크기는 하지만 의 평균인 75,000 WCU를 사용하면 11주 내에 5,000억 개의 항목(백로그)을 완료할 수 있습니다.

이 방법의 과제는 대량 작업이 오가닉 트래픽의 일정한 비율로 실행되도록 유지하는 것이고, 이 비율은 달라질 수 있습니다. 벌크 익스큐터는 Amazon CloudWatch지표를 반드시 확인해야 합니다. 그래서 전체 소비량을 감지하고, 또 최근 대량 작업에 사용된 기록을 차감하여 수학적으로 오가닉 트래픽의 사용 수준을 결정해야 합니다. 그리고 오가닉 트래픽과 고정된 비율로 수행이 되도록 자체 쓰로틀링을 조정해야 합니다. 정확한 예측은 어렵기 때문에 유틸 타겟을 너무 공격적으로 설정하는 것은 좋지 않습니다. 예를 들어 90% 보다는 80% 가 좋습니다.

또 다른 어려운 점은 처리량 초과 예외가 발생하는 경우 이게 테이블 단위의 오류인지 혹은 하나의 핫 파티션이 오류를 유발하는지 구분할 수 없다는 것입니다. 어떠한 경우든 오가닉 트래픽의 쓰로틀링을 피하기 위해서 벌크 작업을 엄격하게 자체적으로 쓰로틀링 해야 합니다. 나중에 설명하겠지만, 중요한 점은 벌크 작업이 파티션 전체에서 고르게 수행될 수 있도록 분산시키는 것입니다. 왜냐하면 하나의 핫 파티션으로 인해 벌크 익스큐터가 중지되는 빈도를 최소화하기 위해서입니다.

앞에서 설명드렸던 방법과 마찬가지로 이 접근 방법도 추가 요금 없이 일정 기간 동안 모든 업데이트를 수행할 수 있습니다. 하지만 엔지니어의 사전 작업이 필요 합니다.

오토 스케일링 제거

만약 프로비저닝 된 용량을 사용하면서 얼마나 오랫동안 벌크 익스큐터를 사용할지 조정하고 싶거나 또는 변경이 되는 변수를 최소화 하고 싶은 경우에, 완전히 무료는 아니지만 오토 스케일링을 제거하는 것으로 비용 효율적인 대량 작업 수행이 가능합니다.

오토 스케일링 기능을 끄고, 테이블을 고정된 프로비저닝의 쓰기 용량을 설정합니다(최대 오가닉 트래픽 이상). 그리고 벌크 익스큐터가 오가닉 트래픽이 프로비전 된 양 사이의 차이를 사용하도록 합니다. 이때 오가닉 트래픽이 제한되지 않도록 벌크 익스큐터가 자체적으로 쓰로틀링 되도록 설정해야 합니다.

비용절감은 대량 프로세스를 수행하는 동안 예비 분의 리소스를 사용하지 않기 때문에 이것을 활용하는 것으로 부터 비용 절감이 가능합니다. 만약 대량 프로세싱이 10주 동안 수행된다면, 해당 기간 동안 필요로 했던 예비 분을 대량 프로세싱 비용에서 차감할 수 있습니다. 사용하지 않은 예비 분은 대량 프로세스처리에 사용됩니다.

벌크 익스큐터는 자체 사용량을 추적해야 하고 또 CloudWatch에서 전체 사용량을 관찰해야 하며 이를 바탕으로 자체 쓰로틀링을 하면서 전체적으로 사용되는 리소스를 프로비저닝 한 수준에 맞도록 해야 합니다. 만약에 처리량 초과 예외가 발생하면 엄격하게 자체적으로 쓰로틀링을 조정해야 합니다.

예상치 못한 오가닉 트래픽의 쓰기 스파이크를 처리할 수 있는 버스트 용량의 이점을 유지하려면 사용 목표 사용량을 100% 보다 조금 낮게 설정해야 합니다. 버스트 용량을 사용하면 짧은 기간 동안 테이블이 프로비저닝 된 용량을 초과 사용이 가능합니다. 버스트 용량 제공이 항상 보장되지는 않지만, 버스트 사용이 가능한 경우 오가닉 트래픽이 급증하는 경우에도 테이블의 쓰로틀링 현상을 피할 수 있습니다. 단 버스트 용량이 모두 소진된 후에는 쓰로틀링 현상이 발생합니다.

버스트에 사용할 수 있는 용량은 초당 프로비저닝 용량의 300배입니다. 예를 들어, 200,000 WCU로 프로비저닝 된 테이블은 테이블 수준(level)에서 쓰로틀링 현상이 발생하기 전에 10분 동안 300,000개 또는 20분 동안 250,000으로 버스트 할 수 있습니다 (개별 파티션은 버스트 용량이 없음). 트래픽이 프로비저닝 된 용량 이하로 시간을 보내면 버스트 용량이 보충됩니다.

전체 소비량보다 차이가 5% 보다 낮은 수준을 유지하면서 100분이 지나면, 전체 용량이 고갈된 후에도 버스트 용량이 허용하는 범위 안에서 완전히 복원이 됩니다. 그렇기 때문에 95% 소비량을 목표로 하는 것이 속도, 비용 효율성, 버스트 가용성 유지 측면에서 좋은 타협책이 될 수 있습니다. 만약에 오가닉 워크로드에 많은 스파이크한 리퀘스트가 발생하는 것이 예상이 된다면, 갭을 크게 잡는 것도 좋은 방법입니다.

아래 차트는 이를 시각화한 것 입니다. 뾰족한 주황식은 오가닉 소비 용량이고, 평평한 (일정한) 파란색은 일반적인 프로비전 용량이며, 빨간색 점은 새로 설정된 프로비전 용량을 의미합니다. 벌크 작업은 평행한 빨간색 선보다 조금 아래에서 작업이 이루어져야 합니다.

Figure 4: 동일한 양을 일정하게 소비를 하기 위해서 오토스케일링 기능을 끄고 대량 작업을 사용 합니다

이 방법은 오토 스케일링의 오버해드에 내재된 비용을 빼고 오가닉 쓰기와 대량 작업의 쓰기를 합쳐서 95% 정도의 사용률을 달성할 수 있습니다. (예: 목표 사용률이 70% 인 경우 비용의 30% 가 예비용도로 사용)

5,000억 개의 항목이 있는 테이블과 프로비저닝 된 800,000 WCU가 있다고 가정해 보겠습니다. 이는 변동이 심한 스파이크 한 오가닉 트래픽이 일반적으로 피크치에 달했을 때 300,000~700,000 WCU 사이가 됩니다. 800,000 WCU는 이 예상되는 최대치를 상회합니다. 대량 트래픽은 오가닉 트래픽과 목표 사용량인 760,000 WCU (전체의 95%) 사이의 차이를 활용할 것입니다. 대량 트래픽의 비율은 다양하지만 오가닉 트래픽의 평균은 500,000 WCU이므로 대량 작업에 평균적으로 260,000 WCU가 할당됩니다. 이 쓰기 속도로는 3주 안에 5,000억 개의 항목을 모두 처리할 수 있습니다.

비용을 생각해 봅시다. 이 3주 동안 벌크 작업이 없다면 평균 500,000개의 WCU의 오가닉 트래픽이 발생할 것으로 예상되며, 목표 사용률이 70% 라면 평균 714,285개의 WCU가 프로비저닝 될 것으로 예상됩니다. 그래서 일정하게 800,000 WCU를 프로비저닝 하기로 선택했습니다. 벌크 익스큐터가 3주 동안 평균 260,000 WCU의 작업을 수행하지만 단지 약 85,000 WCU의 비용만 추가 되었습니다. 즉 대량 작업이 완전히 활용된 프로비저닝된 쓰기에 67%의 비용의 절감을 이루어 내었습니다. 이는 오토 스케일링 테이블을 통한 절약보다도 더 비용 효율적이라는 의미입니다.

이 게시물을 시작할 때 프로비저닝된 테이블을 대상으로 한 벌크 작업에 129,065달러의 비용이 든다고 계산했습니다. 이 방법을 사용하면 3주 동안 평균 85,000 WCU가 소모되며 총비용은 다음과 같습니다.

85,000 WCU * 21일 * 24시간 * WCU-시간당 0.00065달러 = 27,846달러

이는 비용 1달러당 약 18,000,000건의 항목 업데이트에 해당합니다.

접근방법 비교하기

첫 번째 방법인 “미사용 예약 용량사용“ 방법은 간단하고 잠재적으로 무료로 대량 쓰기를 제공합니다. 하지만 이것을 위해서는 예약용량을 적게 사용하는 시간과 주기의 예측이 가능해야 합니다. 미사용 기간이 길고 갭이 클수록 대량작업을 더 빨리 완료할 수 있습니다.

두 번째 접근 방식인 “오토스케일링의 사용률을 타이트하게 사용하는 것”은 더 복잡합니다. 무료의 대량 작업을 달성할 수 있지만 대신에 쓰로틀링의 위험이 높아질 수도 있고 또 오가닉 트래픽 때문에 오토 스케일링이 발생할 수 있는데 오토 스케일링 도중에서도 대량 작업이 작업 수행이 될 수도 있습니다. 이러한 위험 요소들은 오가닉 트래픽에 더해지는 대량 작업의 비율만큼 변수화 하는 것으로 제어하는 것이 가능합니다.

세 번째 접근 방식인 “오토 스케일링 제거”는 단순합니다.  두 번째 옵션보다 빠르게 실행 되지만 대량 작업을 위해 약간의 비용이 발생할 수 있습니다. 왜냐하면 단일 프로비저닝된 사용량이 오토 스케일링의 평균 사용량 보다 높을 수 있기 때문 입니다. 하지만 고정된 프로비저닝량을 선택하게 되면 비용 제어가 가능하게 되고 대량 작업을 수행하는 동안 사용하지 않는 처리량에 대한 비용을 아낄 수가 있습니다.

미사용 예약 용량사용오토 스케일링의 사용률을 타이트 하게 사용오토 스케일링 제거

A B C D
1
2 Summary 예약 용량(RC) 사용이 적은 동안 사용하지 않은 RC를 벌크 작업으로 전환 오토 스케일링 목표를 높이고 대량 작업을 추가 하여 높은 목표도 수용 가능하도록 (이 대량 작업은 오가닉 트래픽이 급증하게 되면 일시적으로 중지) 사용률을 최대한 활용 하기 위해서 높은 고정량의 자원을 프로비저닝 하고 대량 작업을 추가(이 대량 작업은 오가닉 트래픽이 급증하게 되면 일시적으로 중지)
3 Cost 무료 무료 적다
4 Advantages 가장 간단한 디자인 예약 용량(RC)없이도 사용 가능 수행속도 조절 가능; 직관적인 디자인
5 Disadvantages 예약 용량을 활용해야 하며 트래픽이 예측 가능해야함 가장 복잡한 디자인 비용 발생

셔플 스캔을 통하여 쓰기 로드 분산하기

어떤 접근 방식을 선택하든 쓰기 부하를 테이블 파티션 전체에 분산시키는 것이 좋습니다. 만약 테이블 스캔하여 쓰기를 사용한다면 조금 더 주의를 기울여야 합니다.

Scan 호출이 반복될 때는 한 번에 한 페이지씩 가져옵니다. 각 호출은 제한(limit)으로 지정한 크기만큼(최대 1MB) 반환 합니다. 한 번의 요청에 모든 데이터를 가지고 올수 없는 경우에, 이 응답에는 LastEvaluatedKey 가 포함됩니다. 이 키는 다음 Scan 호출에 전달 그다음 페이지를 가지고 오게 됩니다. 내부적으로 Scan 호출은 하나의 파티션에서 데이터를 가지고 온 후 다음 파티션에서 항목을 가져오게 됩니다.

Scan에서 반환된 아이템들로부터 바로 쓰기를 구동하고자 하면 해당 시점에서 Scan이 처리 중인 파티션으로 쓰기를 전송하게 됩니다. 이는 롤링 핫 파티션(rolling hot partition)을 만들게 되고 쓰기 속도가 초당 약 1,000 WCU(파티션의 당 고정 쓰기 한도)로 제한하게 됩니다.

이를 방지하려면 셔플 스캔을 수행하는 것이 좋습니다.

  1. 병렬 스캔을 시작합니다.
  2. 예를 들어 10,000개의 세그먼트처럼, 스캔에 사용할 세그먼트 숫자를 지정합니다.
  3. 한 세그먼트에서 100개의 항목을 가져오고 (제한 사용), 무작위로 선택한 다른 세그먼트에서 100개의 항목을 가져옵니다.
  4. 각 세그먼트 번호의 LastEvaluatedKey를 추적하여 해당 세그먼트로 다시 돌아와서 다음 블록을 읽을 때 다시 사용할 수 있도록 합니다.
  5. 세그먼트가 더 이상 LastEvaluatedKey를 반환하지 않으면 해당 세그먼트를 완전히 읽은 것이므로 다시 읽을 필요가 없게 됩니다.
  6. 모든 세그먼트가 완료되면 전체 테이블이 무작위 순서로 스캔됩니다.

이렇게 하면 테이블의 서로 다른 10,000개 세그먼트에서 한 번에 100개의 항목을 가져와서 여기저기 이동하여 테이블 전체에 잘 분산된 작업 목록을 만들 수 있습니다.

병렬 워커를 사용하는 경우 각 워커에게 무작위 세그먼트 집합을 할당하여 서로 섞이게 할 수 있습니다. 이렇게 하면 각 워커가 자신의 작업을 테이블 전체에 분산할 수 있습니다.

요약

대량 쓰기(또는 등록/삭제/수정)의 경우 비용 효율성을 고려, 작업을 수행하는 시간과 속도를 선택하여 실행할 수 있는 특징이 있습니다.

만약에 예약 용량(Reserved Capacity)이 있고, 또 오가닉 트래픽이 예약 용량 최솟값 보다 적게 사용하는 경우에는 추가 비용 없이 쓰기를 확보할 수 있습니다.

만약 오토 스케일링을 사용한다면, 목표 사용률을 높게 설정하여 그 여유분을 대량 쓰기 작업에 사용하고 그리고 이 쓰기 작업 중에 쓰루풋의 한도에 도달하게 되는 경우에 대량 작업이 철저하게 자체 조절되도록 하여 쓰로틀링 이슈를 방지하는 방법을 통해서 무료 혹은 무료에 가까운 비용으로 쓰기 작업수행이 가능해집니다.

만약에 설계를 단순하게 하거나 빠른 처리를 원한다면, 고정된 프로비저닝 된 WCU 양 (오토스케일링 없이)을 설정하고 대량 작업이 설정한 대부분의 프로비전한 양을 사용함으로써 쓰기 비용을 절감할 수 있습니다. 비용절감은 대량 작업 수행되는 동안 오토 스케일링을 사용해서 발생하는 오버헤드를 제거함으로 이루어집니다.

테이블 스캔을 통해서 대량 쓰기를 실행할 때는, 테이블 전체에 스캔 호출을 분산하고 또한 쓰기 호출도 분산해야 합니다. 그래야 핫 파티션을 피할 수 있습니다. 임의의 세그먼트에서 적은 수의 항목을 반복적으로 가져오는 셔플 스캔 (병렬 스캔을 기반으로 함)을 통하여 이를 구현할 수 있습니다.

AWS 데이터베이스 블로그에서 Jason Hunter가 작성한 더 많은 DynamoDB 게시물 및 기타 게시물을 찾을 수 있습니다.

Yeonsoo Lee

Yeonsoo Lee

이연수 테크니컬 어카운트 매니저는 대규모 엔터프라이즈 시스템 개발과 운영 경험을 바탕으로, Enterprise Support 고객이 클라우드 환경에서 성공적으로 고객의 서비스를 운영할 수 있도록 아키텍처를 수립하고 돕는 역할을 하고 있습니다.

Jiyong Kim

Jiyong Kim

김지용 Technical Account Manager는 통신 및 빅데이타 분야에서 쌓은 다양한 IT 경험을 바탕으로 엔터프라이즈 서포트 고객이 AWS 모범 사례를 기반으로 클라우드 환경을 안정적으로 운영하고 비즈니스 목표를 달성할 수 있도록 도움드리고 있습니다.