AWS DynamoDB - 소개
- 고가용성의 NoSQL 서버리스 데이터베이스
- 여러 AZ에 걸쳐 즉시 복제 가능
- 검색 속도가 빠르고 지연시간 낮음
- 보안, 권한부여, 관리를 위한 IAM과 통합
- DynamoDB Streams를 통해 이벤트 기반 프로그래밍 활성화 가능
- 낮은 비용, 오토스케일링 지원
AWS DynamoDB - 기초
- 각 테이블은 Primary Key(기본 키)를 가짐
- 테이블을 만들기 전에 기본키를 정의해야 함
- 각 테이블은 items(=rows)을 무한으로 가질 수 있음
- 각 item은 속성(attribute)을 가짐 (nullable) (시간이 지나도 추가 가능)
- 각 item의 최대 크기는 400KB
- 데이터 타입 지원
- 스칼라 타입 - 문자열, 숫자, 이진수, boolean, null
- 문서 타입 - List, Map
- 집합 타입 - String Set, Number Set, Binary Set
AWS DynamoDB - 기본키 (Primary Key)
- 옵션 1 - Partition Key (Hash 전략)
- 항목마다 고유해야 함
- 데이터가 분산될 수 있을만큼 다양해야함 (카디널리티가 높은 속성을 택해야함)
- 옵션 2 - Partition Key + Sort Key (Hash + Range 전략)
- 두 항목의 조합은 고유해야 함
- 데이터는 파티션 키를 기준으로 그룹핑됨
- ex) 여러 게임을 하는 사용자에 대해 PK : user_id / SK : game_id
AWS DynamoDB - 읽기 / 쓰기 용량 모드 (Capacity Mode)
- 테이블의 용량을 제어하는 방법
- 프로비저닝 모드 (기본값)
- 초당 읽기/쓰기 처리량 지정 (읽기용량유닛 RCU, 쓰기용량유닛 WCU)
- 사전에 용량을 설정해야함
- 프로비저닝 된 RCU, WCU에 따라 비용 지불
- 사용량에 따라 자동으로 설정해주는 오토스케일링 옵션 설정 가능
- 프로비저닝된 용량보다 더 많은 처리 시 버스트 용량 사용됨
- 버스트 용량까지 모두 소진 시 PrivisionedThroughputExceededException 발생
- 해당 오류 발생 시 지수 백오프를 통한 retry
- 온디맨드 모드
- 워크로드에 기반해 읽기/쓰기를 자동으로 스케일링 (업/다운)
- 사전에 용량 설정 X
- 사용한 만큼만 비용 지불 (프로비저닝 모드보다 훨씬 비쌈, 약 2.5배)
- 성공한 요청을 기반으로 계산 (RRU, WRU, Request Unit)
- 워크로드, 트래픽 예측이 불가능 할 때 사용
- 24시간 마다 모드 변경 가능
- 쓰기 용량 유닛 (WCU)
- 최대 1KB item에 대한 초당 1개의 쓰기
- item이 1KB보다 클 경우 더 많은 WCU 사용
- ex 1) 초당 10 item write / item size 2KB
- 10 * (2KB / 1KB) = 20 WCUs 필요
- ex 2) 초당 6 item write / item size 4.5KB
- 6 * (5KB / 1KB) = 30 WCUs 필요 (WCU 계산 시 소수점은 항상 올림)
- ex 3) 분당 120 item write / item size 2KB
- 2 * (2KB / 1KB) = 4 WCUs 필요
- 읽기 용량 유닛 (RCU)
- DynamoDB 내부적으로는 여러 대의 서버가 존재
- 애플리케이션에는 하나의 서버에만 쓰기하지만, 내부적으로 서버2, 서버3과 같은 서버에 쓰기 복제
- 애플리케이션에서 읽기 시 서버2, 서버3에서 읽을 수도 있음
- Strongly Consistent Read
- 쓰기 이후 읽기 시 짧은 간격이어도 최신 데이터를 읽음
- 이를 설정하기 위해 GetItem, BatchGetItem, Query, Scan 등 API에서 ConsistentRead = true로 두어야함
- 해당 읽기 방식은 RCU를 2번 소비하므로 기본값으로 되어있지 않음 (비싼 읽기비용, 지연시간 높음)
- Eventually Consistent Read (기본값)
- 쓰기 후 읽기 시 오래된 데이터를 읽을 가능성이 있음 (짧은 간격일 경우 복제 전일 수 있음)
- 크기가 최대 4KB인 item마다 초당 SCR 1개 or ECR 2개
- 4KB보다 크면 더 많은 RCU 소비
- ex 1) 초당 10 SCR / item size 4KB
- 10 * (4KB / 4KB) = 10 RCUs 필요
- ex 2) 초당 16 ECR / item size 12KB
- (16 / 2) * (12KB / 4KB) = 24 RCUs 필요
- ex 3) 초당 10 SCR / item size 6KB
- 10 * (8KB / 4KB) = 20 RCUs 필요 (6KB는 가장 가까운 4KB로 올림)
AWS DynamoDB - 파티션
- 테이블마다 파티션이 나눠져 있으며 데이터는 파티션에 저장
- 모든 데이터는 해싱 알고리즘을 거침
- 해싱 알고리즘을 통해 파티션키에 해당하는 파티션으로 분산되어 저장
- 프로비저닝 된 WCU, RCU는 각 파티션에 고르게 분배됨
AWS DynamoDB - 쓰로틀링
- 각 파티션마다 RCU, WCU 초과 시 ProvisionedThroughputExceededException 발생
- 사유
- 파티션이 핫키일 수 있음 (특정 파티션에 데이터가 몰림)
- 데이터 사이즈가 너무 큼 (많은 WCU, RCU 소비)
- 해결
- 지수 백오프를 통한 재시도 (SDK 사용시 포함된 해결법)
- 파티션 키를 최대한 분산
- RCU 이슈일 경우 DynamoDB Accelerator 사용 (DAX)
AWS DynamoDB - 기본 API
- Write
- PutItem
- 기본키가 같은 새 항목을 만들거나 완전히 교체
- WCU 소모
- UpdateItem
- 기존 항목 속성 편집. 없을 경우 새 항목 추가
- 원자성 카운터(Atomic Counter)와 함께 사용 가능
- Conditional Writes
- 조건을 충족했을 때만 쓰기/업데이트/삭제 수행
- 항목에 동시 액세스 유용
- PutItem
- Read
- GetItem
- 기본키 기반 읽기 (Hash, Hash + Range)
- Eventually Consistent Read (기본값) / Strongly Consistent Read
- API를 통해 ProjectionExpression 지정 가능 (특정 속성만을 읽을 수 있음)
- Query
- KeyConditionExpression에 따라 항목 반환
- PK (= 연산, 필수)
- SK (=, <, >, Between, Begin with 연산, 선택)
- FilterExpression 지정 가능
- Query 수행 이후 데이터 반환 전에 필터 추가
- non-key 속성에 적용 가능 (Hash, Range에 적용 불가능)
- 리스트 형태로 반환 (limit 설정 시 항목 수 제한)
- 항목 수 제한 도달 or 데이터 용량 최대 1MB 도달 시 반환
- 페이징 처리 가능
- 테이블, 로컬 보조 인덱스, 글로벌 보조 인덱스 쿼리 가능
- KeyConditionExpression에 따라 항목 반환
- Scan
- 테이블 전체를 읽음
- 전체 테이블 반환 - 각 스캔은 최대 1MB 데이터 반환
- 계속 읽어오고자 한다면 페이징 처리
- 전체 테이블을 읽어오므로 많은 RCU 소모
- 정상적인 작업에 영향을 주지 않기 위해서는 limit문을 스캔에 적용 or 결과 크기를 줄이고 pause
- RCU를 많이 사용하는 대신 최대한 빠르게 스캔 작업을 수행하려면 병렬 스캔 (Parallel Scan) 사용
- ProjectionExpression, FilterExpression(클라이언트 측에서 변경, 비효율적)과 함께 사용 가능
- GetItem
- Delete
- DeleteItem
- 개별 항목 삭제 시 사용
- 조건부 삭제 가능
- DeleteTable
- 테이블 및 테이블 내 모든 데이터 삭제
- Scan을 통해 각 항목에 대한 DeleteItem보다 훨씬 빠름
- 전체 삭제를 위해서는 Scan 수행이 아닌 DeleteTable 사용 권장
- DeleteItem
- Batch
- 일괄로 작업을 처리하여 지연시간 절약 API 호출 횟수 감소
- 모든 일괄 작업은 병렬로 수행되어 효율성 높임
- 일부 실패 시 실패항목만 다시 시도 가능
- BatchWriteItem
- 한번 호출로 최대 25개 PutItem / DeleteItem 가능
- 최대 16MB 데이터 기록 가능 / 항목마다 400KB 제한 적용
- 업데이트 불가능 (UpdateItem 사용)
- 항목을 write 할 수 없는 경우에는 UnprocessedItems 반환 -> 지수 백오프로 시도 or WCU 증가 가능
- 주로 WCU 부족으로 인한 이슈
- BatchGetItem
- 하나 이상의 테이블에서 항목 반환
- 최대 100개 항목, 최대 16MB 반환
- 지연시간 최소화를 위해 모든 항목을 병렬적으로 read
- 항목을 read 할 수 없는 경우에는 UnprocessedKeys 반환 -> 지수 백오프로 시도 or WCU 증가 가능
- 주로 RCU 부족으로 인한 이슈
- PartiQL
- SQL 구문을 통해 DynamoDB에서 처리 가능
- Join 불가능
Reference