학습 목표

Amazon DynamoDB — 키로 접근하는 관리형 NoSQL

DynamoDB는 키-값과 문서 모델을 지원하는 완전 관리형 NoSQL 데이터베이스입니다. 서버를 프로비저닝하지 않고, 스토리지는 데이터가 늘어나면 알아서 커집니다. 관계형 데이터베이스와의 결정적 차이는 조인이 없다는 점이고, 그래서 접근 패턴을 먼저 정하고 그에 맞춰 키를 설계합니다.

테이블 · 항목 · 기본 키

기본 키는 두 형태 중 하나입니다. 단순 키는 파티션 키 하나이고, 복합 키는 파티션 키와 정렬 키의 조합입니다. DynamoDB API 문서는 각 키의 역할을 이렇게 정의합니다.

DynamoDB 기본 키를 구성하는 두 가지 키
키 API 값 역할
파티션 키 HASH 내부 해시 함수의 입력이 되어 항목을 파티션에 고르게 분배합니다. 해시 속성이라고도 부릅니다
정렬 키 RANGE 같은 파티션 키를 가진 항목들을 정렬 키 순서로 물리적으로 가까이 저장합니다. 범위 조회의 근거가 됩니다

이 정의 안에 이미 설계 규칙이 들어 있습니다. 파티션 키는 분배를 담당하고 정렬 키는 범위 조회를 담당합니다. "특정 사용자의 최근 주문 20건"처럼 하나의 파티션 안에서 시간순으로 잘라 오는 질의는 복합 키로 자연스럽게 풀립니다.

파티션 키 설계와 핫 파티션 SAA 빈출

DynamoDB 파티션 키 설계와 핫 파티션 DynamoDB 는 항목의 파티션 키 값을 해시해 그 결과로 저장할 파티션을 고릅니다. 왼쪽은 사용자 ID 처럼 값의 가짓수가 아주 많은 키를 쓴 경우입니다. 해시 결과가 골고루 퍼지므로 파티션마다 비슷한 양의 읽기와 쓰기가 걸리고 테이블 전체 용량이 그대로 활용됩니다. 오른쪽은 주문 상태처럼 값이 몇 가지뿐인 키를 쓴 경우입니다. 대부분의 항목이 같은 키 값을 갖기 때문에 같은 파티션으로 몰리고, 그 파티션 하나가 감당할 수 있는 처리량을 넘는 순간 테이블 전체 용량이 남아 있어도 요청이 스로틀됩니다. 이것이 핫 파티션입니다. 아래 두 카드가 해법입니다. 하나는 가짓수가 많은 속성을 파티션 키로 올리고 원래 쓰려던 속성은 정렬 키로 내리는 복합 키 설계이고, 다른 하나는 키 값 뒤에 계산된 접미사를 붙여 같은 논리적 키를 여러 파티션으로 흩뿌리는 방법입니다. 파티션 키 값이 해시되어 파티션이 정해집니다 값의 가짓수가 많은 키 PK = userId 해시 P1 P2 P3 P4 고르게 분배됩니다 테이블 용량이 그대로 쓰입니다 값의 가짓수가 적은 키 PK = status 해시 P1 P2 P3 P4 한 파티션에 몰립니다 스로틀링 발생 테이블 전체 용량이 남아 있어도 막힙니다 해법은 키를 흩뿌리는 것입니다 복합 키로 바꿉니다 PK = customerId · SK = status#날짜 가짓수가 많은 속성을 파티션 키로 올립니다 접미사로 분산합니다 PK = PENDING#07 같은 논리 키를 여러 파티션으로 나눕니다 용량을 올려도 핫 파티션은 풀리지 않습니다 — 고쳐야 하는 것은 키 설계입니다
파티션 키 값이 해시되어 파티션에 분배되는 과정과, 값의 가짓수가 적은 키를 골랐을 때 한 파티션으로 요청이 몰려 스로틀링이 발생하는 상황 — 해법은 파티션 키의 카디널리티를 높이거나 접미사로 쓰기를 흩뿌리는 것입니다

DynamoDB 개발자 안내서는 원칙을 한 문장으로 정리합니다 — "테이블과 보조 인덱스의 모든 논리 파티션 키에 걸쳐 활동이 고르게 일어나도록 설계하라." 같은 문서는 고르지 못한 분배가 만드는 결과를 이렇게 설명합니다. "I/O 요청을 고르게 분배하지 못하는 파티션 키 설계는 '핫' 파티션을 만들어 스로틀링을 유발하고 프로비저닝된 용량을 비효율적으로 쓰게 한다."

무엇이 좋은 키이고 무엇이 나쁜 키인지도 같은 문서가 표로 제시합니다.

파티션 키 값의 분포 균일성 — DynamoDB 개발자 안내서의 비교
파티션 키 값 균일성 왜 그런가
사용자 ID (사용자가 많은 애플리케이션) 좋음 값의 가짓수가 많고 요청이 여러 값으로 흩어집니다
상태 코드 (가능한 값이 몇 개뿐) 나쁨 가짓수가 적어 소수의 파티션에 몰립니다
생성 일시를 일 · 시간 단위로 반올림한 값 나쁨 같은 날에 들어온 모든 신규 항목이 하나의 파티션 키 값으로 몰립니다
디바이스 ID (디바이스들이 비슷한 간격으로 접근) 좋음 가짓수가 많고 트래픽이 고릅니다
디바이스 ID (한 대가 압도적으로 인기) 나쁨 가짓수가 많아도 실제 트래픽이 한 값에 쏠리면 소용없습니다

마지막 두 줄이 시험이 좋아하는 지점입니다. 키의 가짓수가 많다는 것만으로는 충분하지 않습니다. 실제 접근이 몇 개 값에 쏠리면 그 값이 핫 파티션이 됩니다.

쓰기 샤딩 — 접미사로 흩뿌린다

날짜를 파티션 키로 쓸 수밖에 없는 구조라면 쓰기 샤딩(write sharding)을 씁니다. 파티션 키 값에 계산된 접미사를 붙여 하나의 논리 키를 여러 개로 쪼개는 방법입니다. 읽을 때는 접미사 범위를 돌며 질의를 합치면 됩니다.

생성 일자를 그대로 파티션 키로 씁니다. 그날의 모든 쓰기가 하나의 파티션 키 값으로 들어가 테이블 전체 용량을 다 쓰기 전에 스로틀링이 시작됩니다.

안티패턴 — 카디널리티가 낮은 파티션 키
{
  "OrderDate": "2026-07-29",
  "OrderId": "a1b2c3d4",
  "Amount": 12900
}

같은 날짜에 접미사를 붙여 쓰기를 여러 파티션 키 값으로 흩뜨립니다. 읽을 때는 접미사 0부터 N까지 질의해 결과를 합칩니다.

권장 — 접미사로 쓰기를 분산
{
  "OrderDateShard": "2026-07-29#07",
  "OrderId": "a1b2c3d4",
  "Amount": 12900
}

DynamoDB에는 적응 용량(adaptive capacity)도 있습니다. 개발자 안내서는 이 기능이 모든 테이블에서 추가 비용 없이 자동으로 켜져 있으며 불균형한 워크로드를 감당해 스로틀링을 줄인다고 설명합니다. 다만 적응 용량이 나쁜 키 설계를 대신 고쳐 주지는 않습니다. 설계가 먼저이고 적응 용량은 완충 장치입니다.

LSI와 GSI SAA 빈출

기본 키가 아닌 속성으로 조회해야 하면 보조 인덱스를 만듭니다. 종류는 둘이고, 이름의 "로컬"과 "글로벌"이 곧 차이의 요약입니다.

LSI와 GSI의 구조 차이 왼쪽 로컬 보조 인덱스는 기본 테이블과 파티션 키를 공유합니다. 인덱스 항목이 테이블 항목과 같은 파티션 안에 자리 잡기 때문에 정렬 키만 다른 또 하나의 정렬 순서를 얻는 셈이고, 읽기와 쓰기 용량도 테이블 것을 함께 씁니다. 대신 파티션 키 값 하나당 10 GB 라는 크기 제한이 생기고 테이블을 만들 때만 정의할 수 있어 나중에 추가하거나 지울 수 없습니다. 최대 5개입니다. 오른쪽 글로벌 보조 인덱스는 파티션 키를 테이블과 다르게 잡을 수 있고 자기만의 파티션 공간을 갖습니다. 테이블에 쓰기가 일어나면 인덱스로 비동기 전파되며, 읽기와 쓰기 용량을 테이블과 별도로 설정하므로 인덱스 쪽 스로틀링이 테이블과 독립적으로 발생합니다. 크기 제한이 없고 언제든 추가하거나 삭제할 수 있으며 최대 20개입니다. 이미 운영 중인 테이블에 새 조회 패턴을 붙여야 한다는 시나리오의 답은 항상 GSI 입니다. 파티션 공간을 공유하는가, 따로 갖는가 LSI — 로컬 보조 인덱스 같은 파티션 — 파티션 키 = A 기본 테이블 SK = 날짜 항목 LSI SK = 상태 같은 자리에 파티션 키를 테이블과 다르게 잡을 수 없습니다 테이블의 읽기·쓰기 용량을 함께 씁니다 GSI — 글로벌 보조 인덱스 파티션 키 = A 기본 테이블 항목 파티션 키 = B GSI 자기 공간 쓰기가 인덱스로 비동기 전파됩니다 읽기·쓰기 용량을 따로 설정합니다 항목 LSI GSI 파티션 키 테이블과 동일해야 합니다 아무 속성이나 쓸 수 있습니다 최대 개수 5개 20개 크기 제약 파티션 키 값당 10 GB 제한 없음 용량 테이블 용량을 공유 자체 용량 설정 만드는 시점 테이블 생성 시에만 언제든 추가 · 삭제 "이미 운영 중인 테이블에 새 조회 패턴을 추가해야 한다" — 답은 언제나 GSI 입니다
LSI와 GSI의 구조 차이 — LSI는 기본 테이블의 파티션 키를 그대로 쓰고 같은 파티션 안에 자리 잡아 테이블 용량을 함께 쓰는 반면, GSI는 자기 파티션 공간과 자기 용량 설정을 갖고 테이블과 독립적으로 확장합니다
로컬 보조 인덱스와 글로벌 보조 인덱스 비교
항목 LSI (로컬 보조 인덱스) GSI (글로벌 보조 인덱스)
생성 시점 테이블을 만들 때만. 나중에 추가도 삭제도 불가 테이블 생성 시 또는 나중에 언제든 추가·삭제
파티션 키 기본 테이블과 같아야 합니다 기본 테이블과 달라도 됩니다
키 구성 반드시 복합 키 (파티션 키 + 정렬 키) 단순 키 또는 복합 키 모두 가능
읽기 일관성 최종 일관성과 강력한 일관성 중 선택 최종 일관성만. 강력한 일관성 요청 시 오류
용량 기본 테이블의 용량을 함께 씁니다 자체 용량 설정을 갖습니다
개수 상한 테이블당 5개 테이블당 20개 (기본 할당량)
크기 제약 파티션 키 값당 인덱싱된 항목 총합 10 GB 이하 크기 제약 없음
질의 범위 질의에 지정한 파티션 하나 모든 파티션에 걸친 테이블 전체
프로젝션되지 않은 속성 요청하면 DynamoDB가 테이블에서 가져다 줍니다 프로젝션된 속성만 받을 수 있습니다
테이블당 만들 수 있는 보조 인덱스 개수 — 로컬 보조 인덱스는 5개, 글로벌 보조 인덱스는 20개가 기본 할당량입니다. 개수보다 중요한 제약은 로컬 보조 인덱스가 테이블 생성 시에만 만들어진다는 점과 파티션 키 값당 10 GB 크기 제한이 붙는다는 점입니다

표에서 가장 자주 출제되는 두 줄은 생성 시점과 읽기 일관성입니다. DynamoDB API 문서를 보면 근거가 구조에 남아 있습니다 — 기존 테이블을 바꾸는 UpdateTable 작업에는 글로벌 보조 인덱스를 추가·수정·삭제하는 파라미터만 있고 로컬 보조 인덱스를 다루는 파라미터가 없습니다. 같은 API 문서는 글로벌 보조 인덱스에 강력한 일관성 읽기를 요청하면 ValidationException을 받는다고 명시합니다.

용량 모드 — 온디맨드와 프로비저닝

DynamoDB의 처리량 과금 방식은 두 가지이고, API 파라미터 이름과 표시 이름이 다르므로 함께 외웁니다.

DynamoDB 용량 모드의 API 값과 성격
모드 API 값 AWS의 권장 기준
온디맨드 용량 모드 PAY_PER_REQUEST API 문서가 "대부분의 DynamoDB 워크로드에 권장"한다고 명시합니다
프로비저닝된 용량 모드 PROVISIONED "용량 요구를 신뢰성 있게 예측할 수 있는, 예측 가능한 성장세의 안정적인 워크로드"에 권장합니다

결정적인 사실이 하나 더 있습니다 — 이 설정은 나중에 바꿀 수 있습니다. API 문서가 BillingMode에 대해 "이 설정은 나중에 변경할 수 있다"고 적어 두었습니다. 따라서 "처음에는 패턴을 모르니 온디맨드로 시작하고, 패턴이 안정되면 프로비저닝으로 옮긴다"는 전략이 성립합니다.

프로비저닝된 모드에서는 Auto Scaling을 붙여 목표 사용률을 유지하도록 용량을 자동으로 조절할 수 있습니다. 다만 오토스케일링은 지표를 보고 반응하므로 수 초 만에 몇십 배로 뛰는 급증에는 늦을 수 있습니다. 그런 워크로드는 온디맨드가 맞습니다.

두 용량 모드의 상대적인 비용 곡선 — 사용량이 낮고 불규칙한 구간에서는 온디맨드가, 사용량이 높고 안정적인 구간에서는 프로비저닝이 유리해집니다. 의미가 있는 것은 교차점이 존재한다는 사실뿐이며 축의 값은 상대 등급으로, 실제 금액은 리전과 시점에 따라 다릅니다
용량 모드 선택의 판단 기준
요구사항의 신호 선택
트래픽 패턴을 모른다 · 새 애플리케이션이다 온디맨드
급증이 갑작스럽고 예측할 수 없다 온디맨드 — 오토스케일링의 반응 지연을 피합니다
사용량이 드물고 대부분 유휴다 온디맨드 — 쓰지 않는 용량에 돈을 내지 않습니다
부하가 안정적이고 예측 가능하다 프로비저닝 + 오토스케일링
비용을 상한선 안에서 통제해야 한다 프로비저닝 — 용량 상한이 곧 비용 상한이 됩니다

읽기 일관성 옵션

DynamoDB의 읽기는 기본이 최종 일관성(eventually consistent)이고, 요청마다 ConsistentRead를 true로 주면 강력한 일관성(strongly consistent) 읽기가 됩니다.

DynamoDB 읽기 일관성 선택
항목 최종 일관성 읽기 (기본) 강력한 일관성 읽기
방금 쓴 값 이전 값이 보일 수 있습니다 최신 값이 보장됩니다
소비 용량 더 적습니다 더 많습니다
GSI에서 사용 가능 사용 불가 — 요청하면 오류가 반환됩니다
DAX를 거칠 때 캐시에서 응답합니다 캐시를 쓰지 못하고 DynamoDB로 전달됩니다

시험에서는 "읽은 값이 최신임이 보장되어야 한다"는 문장이 신호입니다. 이 조건이 붙으면 GSI로 조회하는 선택지와 DAX로 가속하는 선택지가 함께 소거됩니다. 강력한 일관성 요구는 캐시와 GSI를 동시에 무력화한다는 것이 요점입니다.

DynamoDB 스트림 — 변경을 이벤트로 바꾼다

DynamoDB 스트림에서 Lambda까지의 경로 테이블의 항목이 추가되거나 수정되거나 삭제되면 그 변경 하나하나가 스트림 레코드가 되어 DynamoDB 스트림에 시간 순서대로 쌓입니다. Lambda 는 이 스트림을 이벤트 소스 매핑으로 폴링하며 레코드를 배치로 가져가 처리합니다. 즉 DynamoDB 가 Lambda 를 호출하는 것이 아니라 Lambda 가 가지러 오는 구조이고, 그래서 재시도 규칙도 Lambda 의 비동기 호출 규칙이 아니라 스트림의 규칙을 따릅니다. 스트림을 켤 때 고르는 뷰 타입에 따라 레코드에 담기는 내용이 달라집니다. 키만 담을 수도 있고, 변경 후 항목 전체나 변경 전 항목 전체를 담을 수도 있으며, 둘 다 담을 수도 있습니다. 변경 전후를 비교하는 로직을 짜려면 NEW_AND_OLD_IMAGES 가 필요합니다. 글로벌 테이블의 리전 간 복제도 별도의 장치가 아니라 같은 스트림 위에서 동작합니다. 변경이 레코드가 되고, Lambda 가 가지러 옵니다 DynamoDB 테이블 항목 추가 · 수정 · 삭제 DynamoDB 스트림 변경이 순서대로 쌓입니다 폴링 Lambda 이벤트 소스 매핑 후속 처리 집계 · 알림 · 색인 재시도 규칙도 스트림의 규칙을 따릅니다 글로벌 테이블의 리전 간 복제 별도 장치가 아니라 같은 스트림 위에서 동작합니다 뷰 타입이 레코드에 담기는 내용을 정합니다 StreamViewType 스트림 레코드에 담기는 것 KEYS_ONLY 변경된 항목의 키만 — 가장 가볍습니다 NEW_IMAGE 변경된 뒤의 항목 전체 OLD_IMAGE 변경되기 전의 항목 전체 NEW_AND_OLD_IMAGES 전후 모두 — 변경 내용을 비교하려면 이것이 필요합니다 "항목이 바뀔 때마다 무언가 하고 싶다"의 표준 답은 스트림 + Lambda 이벤트 소스 매핑입니다
테이블 항목의 변경이 스트림 레코드가 되고 AWS Lambda가 이를 폴링해 처리하는 경로 — 뷰 타입에 따라 스트림에 담기는 내용이 달라지며, 글로벌 테이블의 리전 간 복제도 같은 스트림 위에서 동작합니다

스트림을 켜면 항목이 추가 · 수정 · 삭제될 때마다 변경 레코드가 시간 순서대로 쌓입니다. AWS Lambda를 붙이면 변경에 반응하는 처리를 이벤트 기반으로 만들 수 있습니다 — 집계 테이블 갱신, 알림 발송, 검색 색인 갱신이 전형적인 용도입니다.

스트림에 무엇을 담을지는 뷰 타입으로 정합니다. 네 가지입니다.

DynamoDB 스트림의 뷰 타입
뷰 타입 스트림에 담기는 것 언제 고르는가
KEYS_ONLY 변경된 항목의 키 속성만 무엇이 바뀌었는지만 알면 되고, 본문은 다시 읽어도 될 때
NEW_IMAGE 변경 후의 항목 전체 바뀐 결과만 필요할 때
OLD_IMAGE 변경 전의 항목 전체 삭제된 항목을 보존하거나 이전 값을 감사할 때
NEW_AND_OLD_IMAGES 변경 전과 후 모두 차이를 계산해야 할 때. 재고 증감 같은 집계가 대표적입니다

DAX — DynamoDB 전용 인메모리 캐시

Amazon DynamoDB Accelerator(DAX)는 DynamoDB API와 호환되는 캐싱 서비스입니다. DynamoDB 개발자 안내서가 정리한 성격은 세 가지입니다.

내부에는 두 개의 캐시가 있습니다. 항목 캐시는 GetItem·BatchGetItem의 결과를 기본 키로 저장하고, 질의 캐시는 Query·Scan의 결과 집합을 파라미터 값으로 저장합니다. 둘 다 TTL과 LRU 축출이 함께 동작하며, TTL은 클러스터를 만들 때 지정합니다.

같은 문서는 DAX가 적합하지 않은 경우도 명시합니다. 이 목록이 사실상 오답 소거 기준입니다.

고가용성을 위해서는 여러 노드로 클러스터를 구성합니다. DAX API 문서는 노드 수가 1이면 복제본 없는 단일 노드 클러스터가 되고, 내결함성이 필요하면 프라이머리 1대와 읽기 복제본을 둔 다중 노드로 만들라고 안내합니다.

글로벌 테이블 — 다중 리전 다중 활성

글로벌 테이블은 여러 리전에 같은 이름의 테이블을 두고 서로 복제하는 구성입니다. 각 리전의 복제본이 읽기와 쓰기를 모두 받는다는 점에서 주 리전에서만 쓰기를 받는 Aurora 글로벌 데이터베이스와 다릅니다.

복제본으로 추가하려면 조건이 있습니다. API 문서 기준으로 같은 테이블 이름 · 같은 기본 키 · 스트림 활성화가 필요합니다. 복제가 스트림 위에서 동작하기 때문입니다.

TTL — 만료된 항목을 지운다

TTL(Time to Live)은 항목에 담긴 만료 시각 속성을 기준으로 지난 항목을 자동으로 삭제하는 기능입니다. 속성 값은 에포크 시간(초)이어야 하며, 현재 시각보다 작으면 만료로 표시됩니다.

중요한 성질이 두 가지입니다. 첫째, 삭제는 최선 노력(best-effort)입니다. API 문서는 다른 데이터 작업의 처리량을 보장하기 위해 최선 노력으로 삭제하며 대체로 만료 후 이틀 안에 지운다고 명시합니다. 정확한 시각에 사라지지 않습니다. 둘째, TTL 삭제는 쓰기 용량을 소비하지 않습니다.

세션 데이터, 임시 토큰, 로그처럼 수명이 정해진 데이터를 비용 없이 정리하는 것이 용도입니다. "오래된 항목을 지우는 배치 작업을 매일 돌린다"는 선택지가 있으면 TTL이 더 나은 답입니다.

백업 — 온디맨드 백업과 특정 시점 복구

DynamoDB의 두 가지 백업 방식
항목 온디맨드 백업 특정 시점 복구(PITR)
무엇인가 요청한 시점의 테이블 전체 백업 지속적 백업을 기반으로 임의 시점으로 복원
개수 제한 제한 없음 해당 없음
복원 가능 범위 백업을 만든 시점 최근 35일 안의 임의 시점. 보존 일수는 1~35일로 설정
최신 복원 지점 해당 없음 대체로 현재 시각 5분 전
처리량 소비 테이블의 프로비저닝된 처리량을 쓰지 않습니다 쓰지 않습니다
용도 장기 보관, 규정 준수, 릴리스 직전 스냅샷 실수로 인한 삭제·덮어쓰기 복구

10장의 RDS 백업과 구조가 같습니다 — 임의 시점으로 되돌리는 것은 PITR, 오래 보관하는 것은 명시적 백업입니다.

Amazon ElastiCache — Redis와 Memcached

ElastiCache는 인메모리 캐시를 관리형으로 제공합니다. DAX가 DynamoDB 앞에만 붙는 전용 캐시인 것과 달리, ElastiCache는 어떤 데이터 소스 앞에도 놓을 수 있는 범용 캐시입니다. 대신 무엇을 캐시하고 언제 무효화할지는 애플리케이션이 책임집니다.

선택 기준 — 기능이 필요한가, 단순함이 필요한가

두 엔진의 차이는 API 구조에 그대로 드러납니다. Redis 쪽에는 복제 그룹 · 자동 장애 조치 · 스냅샷 · 샤드 재구성 API가 있고, Memcached 쪽에는 그런 API가 없습니다.

ElastiCache 엔진 선택 기준
요구 Redis Memcached
데이터 구조 목록 · 집합 · 정렬된 집합 · 해시 등 풍부한 자료구조 단순 키-값 문자열
복제와 읽기 확장 복제 그룹 — 프라이머리 1대와 읽기 전용 복제본들. 쓰기는 비동기로 전파 복제 없음. 노드끼리 데이터를 공유하지 않습니다
자동 장애 조치 지원 — 복제본이 프라이머리로 승격됩니다 없음. 노드가 죽으면 그 노드의 데이터가 사라집니다
백업(스냅샷) 지원 불가 — 스냅샷 API가 Redis 계열에서만 유효합니다
저장 시 암호화 · 전송 중 암호화 지원 해당 파라미터가 Redis 계열 전용입니다
수평 확장 방식 클러스터 모드에서 샤드로 나눕니다 노드를 늘려 메모리 풀을 키웁니다 (여러 가용 영역에 배치 가능)
멀티스레드 단일 스레드 중심 멀티스레드 — 단순 캐시 작업에서 코어를 더 씁니다
전형적인 용도 세션 저장소, 리더보드, 순위 계산, 지속성이 필요한 캐시, 발행·구독 단순 객체 캐시, 잃어버려도 되는 데이터, 수평으로 크게 키우는 캐시 풀

정리하면 기본값은 Redis이고, Memcached는 "가장 단순한 캐시 풀이면 충분하다"가 명시될 때 고릅니다. 시험 문항에서 지속성 · 복제 · 장애 조치 · 스냅샷 · 자료구조 중 하나라도 요구되면 Memcached는 그 자리에서 소거됩니다.

캐시 계층 선택 — 무엇을 언제 SAA 빈출

"읽기가 느리다"는 같은 증상에 네 가지 처방이 붙습니다. ElastiCache · DAX · 읽기 전용 복제본 · Amazon CloudFront. 이 넷을 가르는 기준은 성능 수치가 아니라 데이터가 어디에 있고, 누가 캐시 로직을 책임지며, 무엇을 캐시하는가입니다.

캐시 계층이 놓이는 자리 — DAX와 ElastiCache 왼쪽 DynamoDB Accelerator 는 DynamoDB 앞에만 놓이는 전용 캐시입니다. 애플리케이션은 DynamoDB API 를 그대로 호출하고 SDK 클라이언트만 DAX 클라이언트로 바꾸면 되므로 캐시 조회와 채우기 로직을 따로 짤 일이 거의 없습니다. 대신 DynamoDB 이외의 데이터 소스에는 쓸 수 없습니다. 오른쪽 ElastiCache 는 Redis 나 Memcached 를 그대로 제공하는 범용 캐시라 RDS 든 DynamoDB 든 외부 API 든 어떤 데이터 소스 앞에도 놓을 수 있습니다. 그 대가로 캐시를 먼저 보고 없으면 원본에서 읽어 캐시에 넣는 지연 로딩, 또는 원본에 쓸 때 캐시도 함께 갱신하는 라이트 스루 같은 채우기 전략과 무효화와 만료 시간 관리를 애플리케이션이 직접 구현해야 합니다. "코드를 거의 바꾸지 않고 DynamoDB 읽기를 빠르게" 라는 요구는 DAX 를, "여러 종류의 데이터 소스 앞에 캐시를" 이라는 요구는 ElastiCache 를 가리킵니다. 캐시가 붙는 자리와 캐시 로직의 주인이 다릅니다 DAX — DynamoDB 앞에만 애플리케이션 DynamoDB API 그대로 DAX 클러스터 캐시 로직은 DAX 안에 DynamoDB SDK 클라이언트만 바꾸면 됩니다 채우기 전략을 짤 일이 거의 없습니다 DynamoDB 이외에는 쓸 수 없습니다 ElastiCache — 아무 소스 앞에나 애플리케이션 ElastiCache Redis · Memcached 임의의 데이터 소스 RDS · DynamoDB · API 지연 로딩 미스 때 채웁니다 라이트 스루 쓸 때 함께 채웁니다 두 전략 모두 애플리케이션이 구현합니다 무효화와 만료 시간도 직접 관리합니다 대신 어떤 데이터 소스 앞에도 놓입니다 "코드를 거의 안 바꾸고 DynamoDB 읽기를 빠르게" 는 DAX "여러 종류의 데이터 소스 앞에 캐시를 두어야 한다" 는 ElastiCache 입니다
캐시 계층이 놓이는 자리 — DAX는 DynamoDB 바로 앞에만 붙고 애플리케이션이 캐시 로직을 거의 짜지 않는 반면, ElastiCache는 임의의 데이터 소스 앞에 놓이며 지연 로딩이나 라이트 스루 같은 채우기 전략을 애플리케이션이 직접 구현해야 합니다
읽기 지연을 줄이는 네 가지 수단의 적용 조건
수단 무엇을 가속하는가 고르는 신호 한계
Amazon CloudFront 사용자와 오리진 사이의 HTTP 응답 전 세계 사용자, 정적 콘텐츠, 반복되는 동일 요청 데이터베이스 질의 자체를 줄이지는 않습니다. HTTP 계층에서만 동작합니다
Amazon ElastiCache 임의의 데이터 소스의 조회 결과 계산 비용이 큰 질의, 세션 저장소, 관계형 데이터베이스 앞의 캐시 캐시 채우기와 무효화를 애플리케이션이 구현해야 합니다
DAX DynamoDB의 읽기 DynamoDB를 쓰고 있고 코드 변경을 최소화하고 싶을 때 DynamoDB 전용이며 최종 일관성 데이터만 제공합니다
읽기 전용 복제본 관계형 데이터베이스의 읽기 처리량 읽기 질의가 다양해 캐시 적중률이 낮을 때, 분석 질의를 분리할 때 복제 지연이 있고, 읽기를 복제본으로 보내도록 애플리케이션 수정이 필요합니다

캐시를 도입하기로 했다면 채우기 전략도 함께 정해야 합니다. 전략은 크게 둘이고, 각각의 대가가 분명합니다.

캐시 채우기 전략의 교환 조건
전략 동작 대가
지연 로딩(lazy loading) 캐시에 없을 때만 원본에서 읽어 와 채웁니다 요청되지 않은 데이터는 캐시에 들어가지 않아 메모리가 절약되지만, 첫 요청은 항상 느리고 오래된 값이 남을 수 있습니다
라이트 스루(write-through) 쓰기가 일어날 때 캐시도 함께 갱신합니다 캐시가 항상 최신에 가깝지만, 읽히지 않을 데이터까지 캐시를 차지하고 쓰기 경로가 무거워집니다

둘을 TTL과 함께 섞어 쓰는 것이 실무의 기본형입니다. 지연 로딩으로 채우되 TTL을 걸어 오래된 값이 무한히 남지 않게 하는 방식입니다.

Amazon Redshift — 데이터 웨어하우스

Redshift는 열 지향 저장과 대규모 병렬 처리를 쓰는 데이터 웨어하우스입니다. 운영 데이터베이스가 한 건을 빠르게 읽고 쓰는 일(OLTP)에 최적화되어 있다면, Redshift는 수억 건을 스캔해 집계하는 일(OLAP)에 최적화되어 있습니다. 같은 데이터를 다루더라도 목적이 다릅니다.

운영 데이터베이스와 Amazon Redshift의 성격 차이
항목 Amazon RDS · Aurora (OLTP) Amazon Redshift (OLAP)
전형적인 질의 키로 몇 건을 읽고 쓰는 트랜잭션 넓은 범위를 스캔해 집계하는 분석 질의
저장 방식 행 지향 열 지향 — 필요한 열만 읽어 스캔량을 줄입니다
확장 구조 인스턴스 크기와 복제본 리더 노드와 여러 컴퓨트 노드로 질의를 병렬 처리합니다
클러스터 구성 해당 없음 API의 ClusterType이 single-node 또는 multi-node입니다
저장 시 암호화 생성 시점에 결정 API의 Encrypted 기본값이 참이며 거짓으로 두려는 요청은 실패합니다

시험에서 Redshift와 자주 붙는 오답이 Amazon Athena입니다. 경계는 이렇습니다 — S3에 있는 데이터를 그때그때 SQL로 조회하면 Athena, 여러 소스를 정기적으로 적재해 두고 반복적으로 분석하면 Redshift입니다. 분석 파이프라인 전체는 15장 데이터 분석 파이프라인에서 다룹니다.

목적별 데이터베이스 — 한 줄 정의

아래 네 가지는 깊이 파고들 대상이 아닙니다. 시험에서는 데이터 모델을 묘사한 문장에서 서비스 이름을 떠올릴 수 있는지만 물어봅니다. 정의 한 줄과 신호 단어를 짝지어 외우면 충분합니다.

목적별 데이터베이스의 용도와 문제문의 신호
서비스 한 줄 정의 문제문의 신호
Amazon DocumentDB MongoDB 호환 문서 데이터베이스 "MongoDB로 만든 애플리케이션을 관리형으로 옮기고 싶다"
Amazon Neptune 그래프 데이터베이스 "소셜 네트워크", "추천", "사기 탐지", "관계를 여러 단계로 따라가는 질의"
Amazon Keyspaces Apache Cassandra 호환 와이드 컬럼 데이터베이스 "Cassandra 워크로드를 서버 관리 없이 운영하고 싶다", "CQL"
Amazon Timestream 시계열 데이터베이스 "IoT 센서 측정값", "시간 순서로 쌓이는 지표를 기간별로 집계"

흔한 오해

시험 포인트 정리

이 장의 주제는 대부분 고성능 아키텍처 설계(24%)에 속하며, 용량 모드와 캐시 도입 판단은 비용 최적화 아키텍처 설계에도 걸칩니다.

확인 문제

이 장의 핵심을 확인하는 10문항입니다. 키보드만으로 완주할 수 있습니다 — 숫자키 1~5로 선택지를 고르고 Enter로 제출합니다.

학습용 유형 연결형과 순서 배열 문항이 섞여 있을 수 있습니다. 두 유형은 암기 확인에 효율이 좋아서 기본개념 확인 문제에만 넣었으며, 실제 SAA-C03 시험에는 출제되지 않습니다.

이어서 볼 곳

공식 문서 출처

이 장의 개념 서술과 API 동작은 모두 아래 문서에서 확인했습니다.