블로그 본문
[서버리스 NoSQL] Amazon DynamoDB의 HTTP 기반 무상태(Stateless) 아키텍처, 파티션 키(PK) 설계 및 초고속 Key-Value 다루기
니꼴라 클라우드 테크 10월 06, 2026📌 목차 바로가기
지난 포스팅에서는 mongodb 공식 클라이언트 드라이버와 .env 환경변수를 활용하여 Express 웹 서버(app.js)에 db.js 연결 모듈 및 userService.js 비즈니스 계층을 모듈화하고, Graceful Shutdown 프로세스를 갖춘 완결된 RESTful API 서비스를 수립했습니다.
로컬 및 가상 서버 기반의 NoSQL 백엔드 구동 원리를 마스터했으니, 이제 클라우드 환경에서 서버 관리 부담을 제로화(Zero Management)하고 초당 수백만 건의 트래픽을 지연 없이 수용하는 AWS 클라우드 매니지드 NoSQL 데이터베이스 파트로 진입합니다. 오늘 포스팅에서는 커넥션 풀 고갈 걱정이 없는 DynamoDB의 HTTP 기반 무상태(Stateless) 통신 메커니즘, 파티션 키(PK) 및 정렬 키(SK) 데이터 모델링, Query vs Scan 비용 제어 수칙, 그리고 AWS CLI 및 Node.js SDK v3 핸즈온 실습을 설명하겠습니다.
1. 커넥션 연결의 패러다임 전환: Stateful TCP 커넥션 풀 vs Stateless HTTP API
전통적인 RDBMS(MySQL) 및 일반적인 NoSQL(MongoDB)은 클라이언트 애플리케이션과 데이터베이스 서버 사이에 지속적인 소켓 연결을 유지하는 상태 유지(Stateful) TCP 커넥션 풀 방식을 기용합니다.
데이터베이스 연결 통신 아키텍처 비교
|
Stateful TCP 커넥션 방식 (MySQL, MongoDB 등) |
Stateless HTTP API 방식 (Amazon DynamoDB) |
|---|---|
|
|
■ Stateful 커넥션 방식의 서버리스 한계
AWS Lambda나 Cloudflare Workers 같은 서버리스(Serverless) 컴퓨팅 환경은 트래픽 폭주 시 순간적으로 수천 개의 분산 컨테이너 인스턴스를 동시 생성합니다. 만약 각 인스턴스가 RDBMS나 MongoDB에 전통적인 TCP 커넥션 수십 개를 개별 생성하면, 데이터베이스의 최대 커넥션 수 limit을 즉각 초과하여 커넥션 고갈(Connection Leak) 및 시스템 마비가 유발됩니다.
■ DynamoDB의 HTTP 무상태(Stateless) 통신 혁신
Amazon DynamoDB는 이 문제를 근본적으로 해결하기 위해 TCP 소켓 커넥션 풀을 전면 폐지했습니다.
- SigV4 인증 기반 HTTPS 통신: 모든 읽기/쓰기 요청은 AWS 서명 버전 4(SigV4)로 암호화된 표준 HTTPS GET/POST 요청으로 전송됩니다.
- 서버리스 완벽 호환: 요청이 들어올 때만 단발성 HTTP 패킷을 발송하고 응답을 수령한 즉시 연결이 종료되므로, 수만 개의 Lambda 함수가 동시 구동되어도 DB 커넥션 풀 고갈 현상이 구조적으로 발생하지 않습니다.
2. DynamoDB 데이터 모델링 핵심: 파티션 키(PK)와 정렬 키(SK) 및 해시 분할 원리
DynamoDB는 고정된 스키마가 없는 테이블 구조를 취하지만, 데이터를 물리 노드에 분산 배치하고 고속 인덱싱하기 위해 주 키(Primary Key) 설계를 엄격하게 규정합니다.
① 단일 파티션 키 (Partition Key / Hash Key)
- 단 하나의 속성(Attribute)을 주 키로 지정하는 구조입니다.
- DynamoDB 내부의 **해시 함수(Hash Function)**가 파티션 키 값을 입력받아 가상 파티션 슬롯 번호를 산출하고, 이에 해당하는 물리적 SSD 저장소 노드에 데이터를 즉시 배치 및 추출합니다.
- 파티션 키 조회는 데이터의 규모가 수백 테라바이트(TB)로 증가하더라도 항상 \(O(1)\)의 일정한 밀리초(ms) 레이턴시를 보장합니다.
② 복합 주 키 (Composite Primary Key: Partition Key + Sort Key)
- 파티션 키(PK)와 정렬 키(Sort Key / Range Key) 두 개의 속성을 조합하여 고유성을 구성하는 구조입니다.
- 동일한 파티션 키를 공유하는 항목들은 물리적으로 동일한 파티션 노드 내에 모여 적재되며, 정렬 키(SK) 수치를 기준으로 디스크에 정렬 상태로 저장됩니다.
- 실무 활용 예시: 고객 ID를
PK(CUST#1001), 주문 일시를SK(2026-10-06T10:00:00)로 지정하면, 특정 고객의 주문 내역을 시간순으로 고속 범위 검색(Range Scan)할 수 있습니다.
③ 핫 파티션(Hot Partition) 방지 전략
특정 파티션 키에 요청이 과도하게 몰리는 현상을 **핫 파티션(Hot Partition)**이라 부르며, 이는 해당 노드의 I/O 처리량을 초과시켜 요청 스로틀링(Throttling)을 유발합니다.
- 나쁜 설계: 결제 일자(
2026-10-06)를 PK로 지정하는 경우 \(\rightarrow\) 당일 모든 트래픽이 단 하나의 파티션 노드로 폭주함. - 올바른 설계: 높은 카디널리티(Cardinality)를 가진 고유 식별자(예:
UUID,CUST_ID,ORDER_ID)를 PK로 설정하거나, 파티션 키 뒤에 무작위 난수를 덧붙이는 Suffix 가공 기법을 대입하여 트래픽을 전체 노드로 균등 분산시켜야 합니다.
3. Query vs Scan 연산 비용 차이와 보조 인덱스(GSI/LSI) 설계 수칙
DynamoDB를 가동할 때 백엔드 아키텍트가 가장 경계해야 하는 것은 테이블 전체 스캔(Scan)으로 인한 무분별한 비용 폭탄입니다.
■ Query vs Scan 연산 비교
Query연산: 파티션 키(PK) 조건을 필수 바인딩하여 특정 파티션 노드 내부의 데이터만 타겟팅 검색합니다. 데이터 읽기 용량 단위(RCU) 소모가 매우 적고 속도가 극도로 빠릅니다.Scan연산: 테이블 전체의 모든 파티션 노드를 전수 스캔한 뒤 클라이언트 메모리 단에서 필터링합니다. 데이터 용량이 클수록 RCU 비용이 폭증하고 응답 속도가 치명적으로 지연되므로, 프로덕션 환경에서는 엄격히 금지해야 하는 안티패턴입니다.
■ 보조 인덱스: GSI (Global Secondary Index) vs LSI (Local Secondary Index)
기존 주 키(PK+SK) 이외의 다른 속성으로 Query 검색을 가동해야 할 때 보조 인덱스를 추가 정의합니다.
- LSI (Local Secondary Index): 기존 테이블과 동일한 파티션 키(PK)를 공유하면서 정렬 키(SK)만 다른 속성으로 대체하는 인덱스입니다. 테이블 생성시에만 정의 가능하며, 파티션당 10GB 용량 제한을 받습니다.
- GSI (Global Secondary Index): 기존 테이블과 완전히 다른 파티션 키(PK)와 정렬 키(SK)를 자율 구성하는 강력한 인덱스입니다. 테이블 생성 후에도 언제든 동적으로 추가/삭제할 수 있으며 용량 제한이 없어 실무에서 가장 광범위하게 기용됩니다.
4. Amazon DynamoDB 무상태 아키텍처 및 파티션 수송 다이어그램
클라이언트 애플리케이션 및 Lambda 서버리스 함수가 SigV4 암호화 HTTPS 요청을 가동하고, DynamoDB 내부의 해시 함수가 파티션 키(PK)를 분석하여 SSD 파티션 노드 및 GSI 인덱스로 고속 분산 매핑하는 전체 수송 구조도입니다.
5. [핸즈온 실습] AWS CLI 및 Node.js SDK v3 기반 DynamoDB 연동
AWS CLI 터미널 명령과 Node.js 백엔드에서의 최신 @aws-sdk/client-dynamodb 라이브러리를 가동하여 테이블을 생성하고 데이터를 고속 제어하는 실습 코드입니다.
① AWS CLI를 활용한 DynamoDB 테이블 생성 및 아이템 추가
# 1. Orders 테이블 생성 (PK: cust_id, SK: ord_date)
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=cust_id,AttributeType=S \
AttributeName=ord_date,AttributeType=S \
--key-schema \
AttributeName=cust_id,KeyType=HASH \
AttributeName=ord_date,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
# 2. 아이템 신규 적재 (PutItem)
aws dynamodb put-item \
--table-name Orders \
--item '{
"cust_id": {"S": "CUST#1001"},
"ord_date": {"S": "2026-10-06T10:00:00"},
"ord_amount": {"N": "88000"},
"status": {"S": "PAID"}
}'
# 3. 고속 파티션 쿼리 실행 (Query)
aws dynamodb query \
--table-name Orders \
--key-condition-expression "cust_id = :v1" \
--expression-attribute-values '{":v1": {"S": "CUST#1001"}}'
② Node.js AWS SDK v3 기반 DynamoDB Client 구현 (dynamoClient.js)
/**
* dynamoClient.js - AWS SDK v3 기반 DynamoDB Client 모듈
*/
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { DynamoDBDocumentClient, PutCommand, QueryCommand } = require('@aws-sdk/lib-dynamodb');
// 1. HTTP 무상태 통신 전담 DynamoDB Client 인스턴스 생성
const client = new DynamoDBClient({ region: 'ap-northeast-2' });
const docClient = DynamoDBDocumentClient.from(client);
// 2. 주문 데이터 적재 함수 (PutCommand)
async function createOrder(orderData) {
const command = new PutCommand({
TableName: 'Orders',
Item: {
cust_id: `CUST#${orderData.custId}`,
ord_date: new Date().toISOString(),
ord_amount: orderData.amount,
prod_name: orderData.prodName
}
});
try {
const response = await docClient.send(command);
console.log('DynamoDB 주문 적재 성공:', response);
return response;
} catch (err) {
console.error('DynamoDB 적재 에러:', err);
throw err;
}
}
// 3. 파티션 키 기반 고속 쿼리 함수 (QueryCommand)
async function getOrdersByCustomer(custId) {
const command = new QueryCommand({
TableName: 'Orders',
KeyConditionExpression: 'cust_id = :custId',
ExpressionAttributeValues: {
':custId': `CUST#${custId}`
}
});
try {
const data = await docClient.send(command);
return data.Items;
} catch (err) {
console.error('DynamoDB 쿼리 에러:', err);
throw err;
}
}
module.exports = { createOrder, getOrdersByCustomer };
마치며: 초고속 서버리스 NoSQL 인프라의 등대를 세웠습니다!
이번 포스팅에서는 TCP 커넥션 풀 고갈 우려를 전면 상쇄하는 Amazon DynamoDB의 HTTP 기반 무상태(Stateless) 통신 메커니즘을 체화하고, 파티션 키(PK) 및 정렬 키(SK) 해시 분할 구조, Scan을 배제하는 Query/GSI 인덱싱 수칙, 그리고 AWS SDK v3 연동 모듈을 구축했습니다!
"소켓 커넥션 유지 오버헤드가 발생하는 상태 유지 방식을 탈피하여, HTTP 무상태 통신과 파티션 키 해시 연산으로 무제한 수평 확장을 보장하는 차세대 서버리스 NoSQL 데이터 아키텍처를 완성한 것입니다."
다음 포스팅 [클라우드 DocumentDB] Amazon DocumentDB 클러스터 생성, EC2 인스턴스 기반 TLS/SSL CA 인증서 접속 및 MongoDB API 100% 호환성 검증] 편에서는 db.t3.medium 클러스터 생성, VPC 보안 그룹 27017 포트 제어, global-bundle.pem CA 인증서 다운로드 및 EC2 인스턴스 상에서의 mongosh 보안 접속 테스트 과정을 설명해 드리겠습니다.
오늘 다룬 DynamoDB 무상태 통신이나 파티션 키 설계, AWS SDK v3 연동에 관해 궁금한 점이 있으시다면 주저하지 마시고 운영자 메일로 질문을 남겨주세요. 오늘도 안전하고 똑똑한 클라우딩 라이프 하세요. 감사합니다! 😉
출처
- 이현호. 실무 프로젝트로 완성하는 클라우드 환경에서 DB 구축과 웹 개발. 길벗캠퍼스. 2026.04. (11.1장 'Amazon DynamoDB 개요 및 특징', 318-328페이지 및 11.2장 'DynamoDB 데이터 모델링 및 CLI 실습', 329-338페이지 참조)
- 이현호. "11장. 클라우드 NoSQL 데이터베이스_설명오디오.m4a" 및 "02장. 데이터와 데이터베이스_설명오디오.m4a" 설명 오디오 가이드 스크립트 기반 DynamoDB HTTP Stateless 통신 메커니즘, TCP 커넥션 풀 무필요성, 파티션 키(PK)/정렬 키(SK) 해시 분할 원리, GSI/LSI 인덱싱 및 Scan 연산 비용 위험성 비하인드 대화록 완벽 반영.
- AWS DynamoDB Developer Guide (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/) 및 AWS SDK for JavaScript v3 Developer Guide.
자주 묻는 질문 (FAQ)
Q. Amazon DynamoDB가 RDBMS나 MongoDB와 달리 서버리스(Serverless) 환경에서 TCP 커넥션 풀 고갈 문제를 일으키지 않는 이유는 무엇인가요?
A. HTTP 기반 무상태(Stateless) 통신 구조 때문입니다. 소켓 연결을 상시 유지하는 TCP 커넥션 풀 없이 표준 HTTPS/SigV4 단발성 요청으로 작동하므로, 수만 개의 Lambda 인스턴스가 동시 가동되어도 커넥션 고갈 현상이 발생하지 않습니다.
Q. DynamoDB 데이터 모델링에서 파티션 키(Partition Key)와 정렬 키(Sort Key)의 역할 및 핫 파티션 방지책은 무엇인가요?
A. 해시 함수 기반 물리 노드 배치 및 범위 정렬입니다. 파티션 키는 해시 연산으로 데이터를 특정 SSD 노드에 분산시키고, 정렬 키는 파티션 내 정렬을 담당합니다. 트래픽 집중을 막으려면 카디널리티가 높은 고유 ID를 파티션 키로 지정해야 합니다.
Q. DynamoDB에서 Query 연산 대신 Scan 연산을 가동할 때 발생하는 시스템 및 비용 측면의 위험성은 무엇인가요?
A. 무분별한 RCU 비용 폭증 및 응답 지연입니다. Query는 특정 파티션 노드만 타겟팅하여 O(1) 속도로 읽지만, Scan은 전체 파티션을 전수 탐색하므로 데이터가 누적될수록 막대한 용량 단위(RCU) 비용이 차감되고 처리 속도가 급격히 저하됩니다.
