본문 바로가기

DataBase/DynamoDB

AWS DynamoDB 소개

AWS DynamoDB(NoSQL PaaS, Key/Value Store)

정확한 그림은 아니라지만, 뭐 대충 요런 포지션이 DynamoDB


NoSQL의 사용 이유(RDBMS 한계?)

Row->Document 성 데이터 이동

Scale-up의 한계 -> Scale-out 가능

비정형 데이터의 최적화


DynamoDB

Index는 Local, Global(Optional) Secondary Index 두 Index를 지원(일종의 View로 물리적으로도 저장)


LSI: Hash Key는 기본 테이블 키와 동일, Rang(sort) Key는 선택

제약: 최대 5개, 테이블 생성 시점만 가능, 10GiB 제한(같은 파티션 내 생성되기 때문?)


GSI: Hash Key, Range(sort) 자유롭게 구성 가능

제약: 최대 5개, 테이블 생성 후에도 가능, Async 방식으로 Consistency에 약점

L/G Index를 통해 DynamoDB의 유연성?은 높일 수 있으나, 비용 증가와 이럴거면 RDBMS 쓸거 같음.


LSI/GSI는 그냥 인프라에 따라 적재되는 DynamoDB 용어일뿐이고, 둘 다 파티셔닝에 대한 Hash/Sort Key다.

Item 검색을 위해서는 LSI 혹은 GSI의 Hash + Sort Key만 사용할 수 있다. 이 외의 Attribute로는 조건문의 값으로 사용할 수 없다. 딱 필요한 Key만을 사용하여 Item들을 검색할 수 있다.


가수(hash), 노래(sort), 앨범, 발매시기와 같은 Item이 있다면 가수 혹은 가수와 노래만으로 해당 Item을 검색할 수 있다. 만약 앨범을 통한 검색 기능도 필요하다면 GSI의 Hash Key로 등록하여 또 다른 물리적인 파티션을 만들고 GSI을 통해 검색할 수 있다.


아무튼 기존 RDBMS 모델링 방식과 다르게, API Response 기준으로 DynamoDB를 모델링 해야한다. 제약이 많다. 

복잡성 높은 DB에는 어울리지 않는다. 


그러나 이런 단점에도 불구하고, DynamoDB의 경우 거의 모든 것을 관리해주기 때문에 매우 매력적인 서비스다. 스토리지 자동 확장, IOPS 관리 등 (Aurora도 스토리지 자동 확장은 지원하나, IOPS 병목 문제는 따로 관리를 해야 한다.) 


호텔스닷컴에서 성능 이슈로 Cassandra에서 DynamoDB로 이관한 경험이 블로깅 되어있다. DynamoDB를 이해하는데 많은 도움이 된다. 

(https://medium.com/hotels-com-technology/dynamodb-basics-113f9dba4460)


Stateless 한 DynamoDB는 Lambda와 궁합이 잘 맞는다. 실제 패킷을 보면 443 Port(AWS API)로 동작하며, Say Hello 하고 Bye 한다.


반면 MongoDB의 경우 mongo mongo 하고 Connection을 물고 있는 것을 알 수 있다. 일반적으로 사용하는 mongoose connection의 경우다. Stateless하게도 쓸 수 있을 것 같은데, 잘 모르겠다. 아무튼...

참고: https://www.youtube.com/watch?v=RfOt2bo0bSA(40분 영상인데 더 보강된 발표가 계속 나오므로 최근의 영상부터 시청 권장)

참고: https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/GSI.html

참고: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html


DynamoDB의 API scan 등을 사용하면 "L", "M", "S" 등 각 Value의 Type까지 가져온다. json을 파싱할 때 거슬린다. 아래와 같이 하위 API를 wrapping 한 모듈을 사용하면 편리하다. (기능상 한계는 존재할 듯)

node.js의 경우 const dynamodb = new aws.DynamoDB.DocumentClient();

Python의 경우 boto3.resource('dynamodb')

https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html


boto3.client vs boto3.resource

https://planbs.tistory.com/entry/boto3resource%EC%99%80-boto3client%EC%9D%98-%EC%B0%A8%EC%9D%B4


지원하는 data type은 아래와 같다. date와 같은 type은 없으나, String을 통해 date type과 같이 사용 가능하다. 또한 float type도 없다. Decimal을 통해 json 데이터 변환 후 저장을 해야한다.

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DynamoDBMapper.DataTypes.html

https://blog.ruanbekker.com/blog/2019/02/05/convert-float-to-decimal-data-types-for-boto3-dynamodb-using-python/


여기까지는 일단 패키지 없이 사용한 내용이고, DynamoDB도 dynamoose라는 OMR 관련 패키지가 있다. 직관적인 예제 등으로 설명이 잘 되어 있다.

https://www.npmjs.com/package/dynamoose

https://dynamoosejs.com/


사용법은 기존 mongoose와 비슷하나, connect가 따로 없기 때문에 mongoose connect 부분에서 Dynamoose의 createDynamooseInstance(); 를 이용해야 한다. 또한 population과 같은 다양한 기능도 지원한다.


추가로 GET Item은 1MB의 제약이 있어, scan과 같은 명령어 사용 시에는 LastEvaluatedKey 값을 체크한 후 재귀방식으로 실행이 필요하다. 

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/Scan.html


DynamoDB의 Storage는 Aurora와 같이 자동 확장해준다. 또한 아래 그림과 같이 기준 IO를 설정하고 임계치에 대해 AutoScaling 기능을 사용할 수 있다.


추가로 On-demand라는 기능도 제공한다. 사용자는 IO에 대해 전혀 신경쓸 필요가 없어진다. 물론 몇몇 인덱스에 IO가 몰리면 hot spot에 따른 스키마 변경이 필요할 수도 있긴하다. 인덱스 키를 해쉬로 골고루 분산되게 적용했으며 회피할 수 있다. https://aws.amazon.com/ko/blogs/korea/amazon-dynamodb-on-demand-no-capacity-planning-and-pay-per-request-pricing/ 


실제 사용하면서 계속 내용을 덧붙여서 두서가 없다. 

추가할 내용이 있으면 계속 업데이트 하겠음.


Provisioning vs On-demand 비용을 비교하면, 

Provisioning의 경우 Write/Read Capacity를 기준으로 비용이 발생(https://aws.amazon.com/ko/dynamodb/pricing/provisioned/)

On-demand의 경우 DynamoDB 요청 수를 기준으로 비용이 발생(https://aws.amazon.com/ko/dynamodb/pricing/on-demand/)


일반적으로 최적화 된 Provisioning이라면 가격이 더 저렴할 것으로 보이지만, 최초 On-demand를 사용하고 요청 수를 계산하여 Provisioning과 On-demand 비용 비교하는 것이 좋겠..지?


또한 아래와 같이 DynamoDB는 Global Table이라는 기능을 지원한다. 무엇인고 하면, 

아래와 같이 원하는 리전을 추가하면 각 리전의 DynamoDB의 Table끼리 데이터 동기화가 된다. 개꿀. Write/Read 에 대한 모든 데이터가 동기화 된다. 그러나 Table Item들이 이미 있으면 생성이 불가능하므로, 최초에 생성해야 한다.

글로벌 서비스 시에 매우매우매우 유용하다. 각 리전별 App 서버에서 Endpoint만 변경해주면 된다. 


경험치를 키우기 위해 억지로 토이 프로젝트의 메인 DB를 DynamoDB로 사용해봤는데 개짜증난다. 그러나 완성 후 스키마 변경 등이 자유롭고, 특히 글로벌 서비스 또한 손쉽게 가능한 점이 매력적이었다. 그러나 앞으로 메인 DB로는 쓸 일은 없을 것 같다.


'DataBase > DynamoDB' 카테고리의 다른 글

AWS DynamoDB 소개  (0) 2018.10.02