Programming

[AWS, Certified Developer Associate] DynamoDB - 기초, 용량 모드, 기본 API

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
      • 조건을 충족했을 때만 쓰기/업데이트/삭제 수행
      • 항목에 동시 액세스 유용
  • 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 도달 시 반환
      • 페이징 처리 가능
      • 테이블, 로컬 보조 인덱스, 글로벌 보조 인덱스 쿼리 가능
    • Scan
      • 테이블 전체를 읽음
      • 전체 테이블 반환 - 각 스캔은 최대 1MB 데이터 반환
      • 계속 읽어오고자 한다면 페이징 처리
      • 전체 테이블을 읽어오므로 많은 RCU 소모
      • 정상적인 작업에 영향을 주지 않기 위해서는 limit문을 스캔에 적용 or 결과 크기를 줄이고 pause
      • RCU를 많이 사용하는 대신 최대한 빠르게 스캔 작업을 수행하려면 병렬 스캔 (Parallel Scan) 사용
      • ProjectionExpression, FilterExpression(클라이언트 측에서 변경, 비효율적)과 함께 사용 가능 
  • Delete
    • DeleteItem
      • 개별 항목 삭제 시 사용
      • 조건부 삭제 가능
    • DeleteTable
      • 테이블 및 테이블 내 모든 데이터 삭제
      • Scan을 통해 각 항목에 대한 DeleteItem보다 훨씬 빠름
      • 전체 삭제를 위해서는 Scan 수행이 아닌 DeleteTable 사용 권장
  • 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

Udemy - AWS Certified Developer Associate 시험 합격을 위한 모든 것!