DynamoDB 요청 라우팅의 작동 방식
여러분이 보내는 모든 읽기나 쓰기는 먼저 상태 없는 요청 라우터 함대에 도달합니다. 라우터는 여러분의 파티션 키를 해싱하고, 그 해시를 그 키의 데이터를 소유한 저장 노드에 매핑한 뒤, 요청을 거기로 전달합니다. 그 한 번의 홉이 키 조회 비용을 테이블이 아이템 천 개를 담든 십억 개를 담든 같게 만드는 이유입니다.
DynamoDB 요청 라우팅은 어떻게 작동하나요?
DynamoDB는 모든 요청을 상태 없는 요청 라우터 함대를 통해 라우팅합니다. 라우터는 파티션 키를 해싱하고, 그 해시를 해당 파티션을 소유한 단일 저장 노드에 매핑한 뒤, 읽기 또는 쓰기를 그곳으로 전달합니다. 라우팅은 키의 해시에 대한 순수 함수이므로, 테이블에 아이템이 천 개든 십억 개든 조회 비용은 동일합니다.
- 요청 라우터가 정문입니다. 그것은 여러분의 요청을 받아 파티션 키를 해싱하고 그 파티션을 담은 저장 노드로 라우팅하는 상태 없는 함대입니다 — 스캔도, 전체 테이블 지식도 필요 없습니다.
- 파티션 키가 모든 것을 결정합니다. 라우팅은 파티션 키 해시의 순수 함수입니다. 같은 키,
같은 노드, 매번 — 그래서
GetItem은 O(table size)가 아니라 O(1)입니다. - 하나의 프라이머리, 둘의 세컨더리. 쓰기는 파티션의 프라이머리 노드에 안착하고, 그것은 내구성을 갖추기 전에 가용 영역에 걸친 두 세컨더리에 복제합니다.
- 나쁜 키는 설계를 무력화합니다. 저카디널리티거나 "핫"한 파티션 키는 트래픽을 한 노드로 깔때기처럼 몹니다 — 라우팅은 멀쩡하고, 키가 문제입니다.
라우팅이 해결하는 문제에서 시작하기
SQL에서 왔다면 쿼리 플래너를 그립니다: 통계를 읽고, 인덱스를 고르고, 어쩌면 스캔합니다. 비용은 얼마나 많은 데이터를 건드리는지에 따라 늘어납니다. 그 모델은 어떤 크기에서도 한 자릿수 밀리초 안에 답해야 하는 키-값 저장소에는 맞지 않습니다.
DynamoDB의 답은 단일 아이템 조회를 검색이 아니라 직접 주소로 만드는 것입니다. 파티션 키는 필터링하는 컬럼이 아닙니다 — 데이터가 물리적으로 어디 사는지 계산하는 해시 함수의 입력입니다. 통계도, 플래너도 없습니다.
그게 관계형 사고에서 벗어날 때 받아들이는 거래입니다: 임의 쿼리 유연성을 포기하고 그 대가로 상수 시간 주소 지정을 얻습니다.
요청 라우터를 만나기
요청이 도착하면, 곧장 저장소로 가지 않습니다. 요청 라우터 — 전체 서비스를 떠받치는 상태 없는, 수평으로 확장되는 함대 — 에 도달합니다. (AWS re:Invent "DynamoDB Deep Dive" 세션이 이 프런트엔드 함대를 설명합니다.)
라우터는 세 가지를 하며 자기 데이터는 하나도 담지 않습니다:
- IAM에 대해 요청을 인증하고 인가합니다.
- 그것을 소유한 파티션을 찾기 위해 파티션 키를 해싱합니다.
- 요청을 그 파티션의 저장 노드로 전달합니다.
라우터는 상태가 없으므로, 서비스는 부하 아래에서 그것들을 더 추가합니다. 어느 것도 병목이 아니고 어느 것도 단일 장애점이 아닙니다 — 2007년 Amazon Dynamo 논문이 원래 시스템을 둘러싸고 구축한 바로 그 속성입니다.
라우터를 통해 읽기 하나 따라가기
드론 함대의 텔레메트리 테이블을 봅시다. 아이템은 DroneId(파티션 키)와 ReadingTs(정렬 키)로
키가 지정되며, BatteryPct와 AltitudeM 같은 속성을 가집니다.
드론 하나의 최신 측정값을 요청합니다:
PK = "DRONE#A19F"
SK begins_with "2026-06-23"
라우터가 그것으로 하는 일은 다음과 같습니다. 아래 도입부는 요청을 위에서 아래로 추적합니다 — 하나의 아래쪽 흐름으로 읽으세요.
라우터는 DRONE#A19F를 해싱하고, 그것을 그 키를 소유한 파티션에 매핑한 뒤, 읽기를 그 파티션의
프라이머리 저장 노드로 전달하고, 그것이 아이템을 반환합니다.
핵심 통찰: 해시는 테이블이 가진 파티션이 몇 개든 그중 하나 를 가리킵니다. 라우터는 다른 파티션을 절대 보지 않으므로, 드론 — 과 파티션 — 을 추가해도 이 조회는 느려지지 않습니다.
파티션이 실제로 무엇인지 알기
파티션은 저장과 처리량의 단위입니다. 각각은 상한이 있고(대략 10 GB와 읽기/쓰기 용량의 고정
조각), DynamoDB는 파티션이 어느 한계를 넘어 자라면 그것을 분할합니다. 주어진 파티션 키를 가진
모든 아이템은 같은 파티션에 살며, 그게 한 파티션 키에 대한 Query를 값싸게 만드는 것입니다.
각 파티션은 가용 영역에 걸쳐 퍼진 세 저장 노드에 복제됩니다: 하나의 프라이머리와 둘의 세컨더리.
| 노드 역할 | 처리 | 서빙 가능한 일관성 |
|---|---|---|
| 프라이머리 | 모든 쓰기; 강력한 일관성 읽기 | 강함(자기 최신 쓰기를 봄) |
| 세컨더리 | 최종적 일관성 읽기; 페일오버 | 최종(프라이머리보다 뒤처질 수 있음) |
쓰기는 프라이머리로 가고, 그것은 내구성을 확인 응답하기 전에 세컨더리에 복제합니다. 강력한 일관성 읽기는 최신 쓰기를 반영하도록 프라이머리로 라우팅됩니다. 최종적 일관성 읽기는 아직 따라잡지 못한 세컨더리가 서빙할 수 있습니다 — 절반의 비용, 어쩌면 오래된 값.
지뢰에 이름을 붙이기: 핫 파티션 키
라우팅은 여러분의 파티션 키만큼만 좋습니다. 해시는 키를 고르게 퍼뜨리므로, 키가 고카디널리티이고 트래픽이 고르면 부하가 모든 노드에 퍼집니다. 둘 중 하나라도 깨면 핫 파티션을 얻습니다.
그 텔레메트리를 DroneId 대신 Region으로 키 지정한다고 합시다. 이제 us-east-1의 모든 드론이
하나의 파티션 키를 공유합니다 — 그래서 그들의 모든 읽기와 쓰기가 같은 노드로 해싱됩니다.
라우터는 자기 일을 완벽히 하고 있습니다; 여러분이 막 전체 함대를 단일 파티션의 용량으로 깔때기처럼
몰아넣은 것입니다.
라우터가 노드를 고르는 것을 지켜볼 수는 없지만, 잘 라우팅되는 키를 설계 할 수는 있습니다.
표현식 빌더에서 키 조건을 만들 때, PK = …의 왼쪽에 두는
파티션 키가 라우터가 해싱할 바로 그 값입니다 — 그 값을 고카디널리티로 유지하는 것이 읽기를 서로
다른 노드에 두는 것입니다.
이것이 여러분의 액세스 패턴으로 어떻게 이어지는가
요청 라우팅은 단일 테이블 설계 규칙을 타협 불가하게 만드는
메커니즘입니다: 파티션 키가 곧 주소이기 때문에 파티션 키를 중심으로 모델링합니다. 또한
Query가 Scan을 이기는 이유입니다 — Query는 라우터를 통해 한
파티션을 치고, Scan은 모든 파티션을 차례로 걷습니다.
보조 인덱스는 자기만의 파티션과 자기만의 라우팅을 가집니다: GSI는 자기만의 파티션 키로 라우팅되며, 베이스 테이블의 것과 독립적입니다 — 그래서 테이블이 핫하지 않을 때조차 GSI는 핫할 수 있습니다.
다음 단계
하나가 아니라 많은 노드로 라우팅되는 키를 설계하세요. 표현식 빌더에서
PK = … 조건을 스케치해 어떤 값이 해싱되는지 정확히 보고, 그런 다음 DynoTable을 다운로드해
여러분 자신의 테이블에 대해 그 쿼리를 돌리고 어떤 파티션 키가 실제로 여러분의 트래픽을
나르는지 지켜보세요.