본문 바로가기
aws

AWS DynamoDB

by 초특급하품 2020. 4. 26.

AWS DynamoDB는 fully managed 서비스로 NoSQL serverless database이다. mysql과 달리 database도 생성할 필요 없이 table만 추가해서 사용할 수 있으며 auto scaling으로 비용을 관리할 수 있고, 빠르고 일관된 성능을 보장한다. 어느새 multi table transaction 기능도 추가되어 유용하게 사용 가능하다.

 

 

Primary Key

Partition key

테이블을 생성할 때 partition key를 지정한다. partition key는 테이블 내에서 유일해야 하며 아이템은 partition key의 hash값으로 분포되어 해당 partition에 저장된다.

 

전체 partition 수는 아래에서 설명할 성능 지표와 테이블 크기를 고려해서 설정된다.

CELING(MAX( (Total RCU / 3000) + (Total WCU / 1000), (Total Size / 10G) )

sort key

테이블 생성 시 partition key에 추가로 sork key를 지정할 수 있다. sort key를 지정하면 partition key + sort key가 테이블 내에서 유일해야 하고, partition 내에서 sort key로 범위에 대한 질의를 빠르게 할 수 있다.

 

 

Index

LSI(Local Secondary Index)

LSI는 테이블 생성 시 특정 키에 대해 지정할 수 있으며 partition key로 나뉜 후 해당 키에 대해 빠르게 질의할 수 있다. partition key에 속해있기 때문에 local이라 불린다. 그렇기 때문에 생성할 때 LSI의 primary key가 원본 테이블의 primary key와 같아야만 생성된다.

 

GSI(Global Secondary Index)

보통은 partition key와 sort key 말고도 다른 키에 대해서 빠른 질의를 해야 하는 경우가 생긴다.

GSI는 검색하고자 하는 키를 partition key로 새로 설정해서 이를 해결한다. 사실상 원하는 키를 partition key로 가지는 새로운 테이블을 만드는 것과 비슷하다. 따라서 GSI를 생성할 때 RCU와 WCU도 설정이 필요하다.

원본 테이블의 변경이 GSI에도 전파되어야 하는데, GSI의 throttling에 걸리면 원본 테이블까지 영향이 끼친다. 따라서 GSI의 RCU, WCU를 설정할 때는 이를 고려해서 충분한 값으로 설정해야 한다.

 

 

Throughput

DynamoDB는 완전 관리형이지만 최소한으로 read/write 용량은 provision 해야 한다.

 

RCU(Read Capacity Units)

읽기의 종류는 총 두 가지가 있다.

  1. Eventual Consistent Read: 이전에 write 한 게 충분히 전파되지 않았을 경우 consistent는 보장하지 않음
  2. Strong Consistent Read: consistent를 보장

최대 4KB 크기 내에서 2 ECR 또는 1 SCR 당 1 RCU가 소모된다. SCR이 ECR보다 두배 더 비싸다. 4KB가 넘어가는 경우에는 4KB로 나눈 값만큼 소모된다. 물론 나머지는 올림 해서 계산한다.

 

이해를 위해 잠시 뒤 돌아가 보면 LSI는 원본 테이블 데이터에 저장되어 있기 때문에 Eventual Consistent Read, Strong Consistent Read 둘 다 가능하고, GSI는 비동기로 전파되기 때문에 Eventual Consistent Read만 가능하다.

 

WCU(Write Capacity Units)

1KB 이하의 데이터를 처리할 때 1 WCU가 소모된다. 데이터가 1KB가 넘어가면 1KB로 나눈 만큼 소모된다. 역시 나머지는 올림 한다.

 

 

auto scaling 기능으로 RCU, WCU를 요청량에 따라 조절할 수 있다. 원본 테이블과 뗄 수 없는 관계인 Global Secondary Index에도 같은 기준으로 적용할 수 있다.

 

 

Throttling

위에 설정한 RCU, WCU를 초과하면 ProvisionedThroughputExceededException 이 떨어진다.

DynamoDB 차원에서 RCU, WCU를 설정했지만 실제 연산을 하는 분산된 partition들은 이 설정값을 n 등분한 성능을 가진다. 예를 들어 테이블의 RCU를 100으로 설정해놔도 partition이 10개라면 하나의 partition은 10 RCU를 가진다. 따라서 전체 요청은 작아도 특정 primary key에 대해 요청이 몰린다면 예상치 못한 에러를 받을 수 있다.

 

이 경우는 exponential backoff로 retry를 해야 하는데 aws SDK에는 이미 구현되어 있다. 

근본적으로 이런 hot partition 문제를 해결하려면 partition key를 겹치지 않게 잘 설정해야 한다. 특정 키에 대한 요청이 많은 경우에는 쓰기 샤딩을 구현하기도 한다. 읽기에 집중해서 해결한다면 DAX(DynamoDB Accelerator)를 앞단 cache로 두어 RCU 소모를 막을 수 있다.

 

 

Stream

create/update/delete 등의 이벤트를 처리 후 DynamoDB Stream으로 전달해서 lambda를 trigger 할 수 있다. 서비스 상에서 데이터를 처리하는 테이블에 stream을 연결하고 lambda로 이벤트를 받아서 가공한 후, 분석 테이블이나 Elasticsearch 등으로 업데이트하도록 설계할 수 있다.

 

 

Free tier

25GB, 25 RCU, 25 WCU 만큼의 프리티어가 지원된다. 월 단위로 2억 개의 요청을 처리하는 수치로 토이 프로젝트로 진행하기에는 매우 훌륭하다.

 

 

'aws' 카테고리의 다른 글

AWS API Gateway  (0) 2020.05.02
AWS Lambda  (0) 2020.04.27
AWS ECS dynamic port mapping  (0) 2020.04.22
AWS VPC를 연결하는 서비스  (0) 2020.04.19
AWS SNS(Simple Notification Service)  (0) 2020.04.12

댓글