DynamoDB 적응형 용량
DynamoDB는 테이블을 파티션에 걸쳐 퍼뜨리지만, 트래픽이 고르게 퍼지는 일은 드뭅니다. 버스트 용량과 적응형 용량은 치우친 워크로드가 스로틀되는 것을 막는 두 가지 자동 메커니즘입니다 — 단단한 한계에 부딪히기 전까지는요.
DynamoDB 적응형 용량이란 무엇인가요?
DynamoDB 적응형 용량은 쓰이지 않은 처리량을 쪽으로 옮겨, 치우친 키가 스로틀되는 동안 테이블의 나머지가 놀고 있지 않도록 하는 자동 메커니즘입니다. 버스트 용량과 짝을 이루어 스파이크와 지속되는 치우침을 무료로 흡수합니다 — 다만 단일 키를 파티션 상한 너머로 밀어붙일 수는 없습니다.
- 버스트 용량은 짧은 스파이크를 넘기도록 최대 5분(300초)의 쓰이지 않은 처리량을 빌려줍니다. 튜닝하는 기능이 아니라 버퍼입니다.
- 적응형 용량은 "핫" 파티션의 처리량을 자동으로 — 테이블의 나머지 쓰이지 않은 용량에서 끌어와 — 올려, 치우친 키가 스로틀되지 않게 합니다.
- 심지어 핫 아이템을 격리해 자기만의 파티션에 두어, 단일 키에 파티션 상한인 3,000 RCU / 1,000 WCU까지 줍니다.
- 키 설계를 무시해도 된다는 면허가 아닙니다. 파티션당 상한을 넘어서면 빌릴 데가 더는 남지 않습니다 — 진짜로 핫한 키는 여전히 스로틀됩니다.
먼저 파티션 상한을 아세요
모든 파티션은 독립적으로 상한이 있습니다: 초당 3,000 읽기 단위와 1,000 쓰기 단위. 그 한계는 프로비저닝이 아니라 물리적입니다 — 프로비저닝 테이블과 온디맨드 테이블 모두에 적용됩니다. (AWS, 버스트 및 적응형 용량.)
SQL에서 왔다면 전체 서버 부하를 따집니다. DynamoDB에서 스로틀되는 단위는 단일 파티션이며, 치우친 키 하나가 무너질 수 있는데도 테이블은 90% 놀고 있을 수 있습니다. 그게 두 메커니즘이 메우려고 존재하는 간극입니다.
버스트 용량이 짧은 스파이크를 흡수합니다
파티션의 처리량을 다 쓰지 않을 때마다, DynamoDB는 남은 것을 적립합니다. 그 쓰이지 않은 용량 중 최대 300초 분량이 예비로 보관되며, 갑작스러운 버스트가 평소 초당 속도가 허용하는 것보다 빠르게 그것을 비울 수 있습니다.
그것은 보이지 않고 자동입니다. 크기를 정할 수 없고, DynamoDB가 자기 백그라운드 작업에 일부를 조용히 쓸 수도 있습니다. 버스트성 트래픽을 위한 쿠션으로 다루세요 — 절대 계획하고 기댈 수 있는 여유로 여기지 마세요.
적응형 용량이 핫 파티션을 부스트합니다
버스트 용량은 짧은 스파이크를 다룹니다. 적응형 용량은 지속되는 치우침을 다룹니다. 한 파티션이 핫하게 도는 동안 이웃들이 놀고 있으면, DynamoDB는 처리량을 핫한 쪽으로 옮깁니다 — 테이블 총합과 파티션 상한까지요.
VEHICLE#<id>(파티션)와 TS#<epoch>(정렬)로 키가 지정된 차량 텔레메트리 테이블을 운영한다고
합시다. 깜짝 세일 구역에 있는 배달 밴 하나가 다른 어느 것보다 10배의 핑을 내보냅니다. 그
파티션은 핫하고, 나머지 200대 밴의 파티션은 거의 놀고 있습니다.
적응형 용량이 이를 알아채고 그 한 파티션의 처리량을 들어 올리며, 차가운 파티션의 쓰이지 않은 용량에서 끌어옵니다. 설정도, 비용도, 워밍업도 없습니다 — 2019년 5월 이래 부스트는 사실상 즉각적입니다. (AWS Database Blog, "How DynamoDB adaptive capacity accommodates uneven access patterns".)
핫한 밴의 파티션은 150 WCU가 필요하지만 100 WCU의 균등 몫으로는 스로틀됩니다. 적응형 용량이 차가운 파티션에서 유휴 WCU를 빌려 그것을 채웁니다.
격리: 단일 아이템이 문제일 때
치우침이 항상 키별인 것은 아닙니다 — 때로는 단일 아이템 이 새하얗게 핫합니다. 끈질긴
트래픽이 하나의 VEHICLE#HOT 아이템을 몰아붙이면, DynamoDB의 split-for-heat가 파티션을
재조정해 그 자주 접근되는 아이템이 혼자 안착하게 합니다.
격리되고 나면, 그 단일 아이템의 키는 파티션 상한: 3,000 RCU와 1,000 WCU 전부를 끌어올 수 있습니다. 그것이 단일 키의 절대 천장입니다 — 그 위에는 어떤 메커니즘도 없습니다. (AWS, Key range throughput exceeded.)
짚어 둘 만한 한 가지 단서: 적응형 용량은 테이블에 Local Secondary Index가 있을 때 아이템 컬렉션을 파티션에 걸쳐 분할하지 않습니다. LSI는 컬렉션을 하나의 파티션에 묶습니다 — 이유는 GSI vs LSI를 보세요.
적응형 용량이 구해 줄 수 없을 때
이게 함정입니다. 두 메커니즘 모두 처리량을 이리저리 옮길 뿐, 어느 것도 파티션이 물리적으로 허용하는 것보다 많이 만들어 내지 않습니다.
| 시나리오 | 버스트 | 적응형 | 결과 |
|---|---|---|---|
| 짧은 스파이크, 테이블에 여유 있음 | 처리함 | — | 스로틀 없음 |
| 지속되는 치우침, 차가운 이웃 | — | 핫 부스트 | 스로틀 없음 |
| 단일 아이템, < 3K RCU / 1K WCU | — | 격리함 | 스로틀 없음 |
| 단일 아이템, **> 파티션 상한 | 빠르게 소진 | 천장에 도달 | 스로틀 — 재설계 필요** |
| 여러 키가 동시에 핫, 테이블 최대치 | 빠르게 소진 | 놀 게 없음 | 스로틀 — 재설계 필요 |
단일 키가 정당하게 초당 1,000 쓰기 이상을 필요로 한다면, 어떤 자동 메커니즘도 여러분을 구하지 못합니다 — 부하를 더 많은 키에 퍼뜨려야 합니다.
쓰기 샤딩이 흔한 해법입니다: 접미사를 붙여(VEHICLE#HOT#0 … #9) 쓰기가 파티션에 걸쳐
부채꼴로 펼쳐지게 한 다음, 읽기를 다시 모읍니다.
그 모으기 자체가 의도적으로 모델링해야 할 액세스 패턴이며, 단일 테이블 설계에서 쿼리 경로를 계획하듯 다뤄야 합니다 — 적응형 용량은 시간을 벌어 줄 뿐, 키 설계에 대한 무임승차권이 아닙니다.
여러분 자신의 테이블에서 보기
적응형 용량은 설계상 보이지 않으므로, 한 가지 증상을 통해 그것을 따집니다: 어떤 키가 핫한가.
샤딩된 쓰기 경로를 만들 때, 표현식 빌더는 접미사가 붙은
키에 대한 PutItem과 Query 구문을 생성합니다.
키가 데이터에 걸쳐 실제로 어떻게 분포하는지 보려면, DynoTable을 다운로드해 적응형 용량이 알아서 해 준다고 가정하기 전에 여러분의 실제 테이블에서 파티션 분산을 점검하세요. 치우침의 읽기 쪽에 대해서는 Query vs Scan을 보세요.