기존의 RDS의 문제점
- 더 좋은 성능의 데이터베이스를 원한다고 했을 때 RDS는 수직적 스케일링밖에 하지 못 한다.
- 물론 수평적 스케일링도 가능하지만, 읽기 전용 복제본을 만들어 부하를 분산 시키는 방법 밖엔 없다.
- RDS에는 수평적 쓰기 스케일링은 존재하지 않는다.
- 이러한 문제점을 해결하기 위해 NoSQL 데이터베이스가 나타났다. (DynamoDB)
NOSQL Database
- NoSql은 수평적 확장성을 갖는다.
- 유명한 기술로는 몽고 디비와 다이나모 디비가 있다.
- 그러나 지원되지 않는 쿼리문이 굉장히 많다.
- sum, avg 같은 집계 연산이나 쿼리문이 지원되지 않기 때문에, 수평 확장성을 갖는다.
Amazon DynamoDB
- 고 가용성의 NoSQL 데이터베이스이다.
- 여러 가용 영역에 걸쳐 즉시 복제가 가능하다.
- 항상 빠른 성능을 보장한다. 일관성 있게 빠르다.
- 검색 시 지연 시간이 낮고, AWS 서비스 이기 때문에 IAM과 완전히 통합되어 보안, 권한 부여 등이 가능하다.
- 비용이 저렴하고 오토 스케일링 기능이 있다.
DynamoDB - Basics
- 테이블로 구성되며, 각 테이블은 기본 키를 가져야 한다.
- 각 테이블은 item이라는 행을 무한대로 가질 수 있다.
- 아이템의 최대 크기는 400KB 이다.
- 각 item은 속성을 가지고 있다. 속성은 테이블의 열과 비슷하다.
- 속성은 시간이 지나도 추가할 수 있다.
- 테이블을 만들 때 모든 것을 정의할 필요가 없다.
- 지원되는 데이터 타입은
- String, Number, Binary, Boolean, Null
- List, Map
- String Set, Number Set, Binary Set 이 있다.
DynamoDB - 기본 키
- 기본 키에는 두 개의 옵션이 있다.
- 첫 번째는 파티션 키 (Hash)
- 키가 아이템 별로 고유해야 한다.
- 따라서 키는 매우 다양해야 한다. 분산에 대비해서
- 두 번재 옵션은 파티션 키 + sort 키 (Hash + Range)
- 각각의 item 마다 두 키의 조합이 반드시 고유해야 한다.
- 데이터는 파티션 키에 의해 그룹으로 묶인다.
- 예를 들어, 유저 아이디를 파티션 키로, 유저의 게임 수행 아이디를 정렬 키로 선택하면
- 유저 별로 묶어서, 게임 판 수마다의 정보를 확인할 수 있다.
DynamoDB - 읽기/ 쓰기 용량
- 테이블의 읽기와 쓰기의 처리량을 조절할 수 있다. 사전에 설정해두어야 한다.
- Provisioned Mode(default)
- 초당 읽기와 쓰기 용량을 지정해야 한다.
- 사전에 용량을 미리 설정해야 한다.
- 설정한 용량만큼, 매 시간 비용을 지불하게 된다.
- On-Demant Mode
- 작업량을 기반으로, 읽기와 쓰기를 자동으로 스케일 업, 다운 한다.
- 사용한 만큼 비용을 지불하나, 프로비전 모드 보다는 훨씬 비싸다.
- 24 시간마다, 프로비저닝 모드와 온디맨드 모드를 바꿀 수 있다.
RW Capacity Modes - Provisioned
- 읽기 쓰기 용량을 프로비저닝 해야한다.
- RCU (Read Capacity Units) - 읽기 처리량을 뜻한다.
- WCU (Write Capacity Units) - 쓰기 처리량을 의미한다.
- 수요를 맞추기 위해서, 처리량을 오토 스케일링하는 옵션이 있다.
- 만약 사전 정의된 사용량보다, 더 많은 처리량이 들어올 경우도 괜찮다.
- 버스트 모드가 있어서 일시적으로 처리 가능하다.
- 만약 버스트 모드의 용량을 다 쓴 경우 프로비저닝 처리량 초과 예외가 발생한다.
- 지수 백오프 전략을 사용해서 작업을 다시 시도해야 한다.
DynamoDB - WCU
- 1 WCU란, 초당 1KB의 아이템을 쓸 수 있다는 것이다.
- 그래서 아이템이 만약 2KB라면, 우리는 프로비저닝 할 때 2 WCU를 설정해야 한다.
- 문제 예시를 들어보자, 초당 10개의 아이템이 적히고, 아이템은 개당 2KB라고 한다면 몇의 WCU가 필요할까?
- 정답은 20 WCU이다.
- 계산 방법이 참 이상한데, 한 아이템이 4.5 KB이고 초당 6개의 아이템이 적힌다고 하면
- 한 아이템을 적는 데 필요한 WCU는 항상 반올림 되어 계산 된다고 한다.
- 즉, 4.5KB는 4.5 WCU가 필요한 것이므로, 5 WCU가 필요한 것이고 초당 6개의 아이템이 적히니, 30 WCU가 필요한 것이다.
DynamoDB - RCU - mode
- Strongly Consistent Read 모드와
- Eventually Consistent Read 모드 두 가지가 있다.
- 다이나모 디비는 실제론 다음과 같이 여러 대의 서버로 이뤄져 있다.
- 여기서 문제가 발생하는데 바로 동기화 문제다.
- 만약 서버1에 데이터를 작성하고, 바로 서버2에서 읽기가 수행된다면, 오래된 데이터를 읽을 가능성이 있는 것이다.
- 이것 때문에 두 가지 모드가 존재한다.
- 첫 번째는 Eventually Consistent Read (Default) 모드로, 오래된 데이터를 읽을 가능성이 존재하는 모드다.
- 두 번째는 Strongly Consistent Read 모드로 항상 정확한 데이터를 읽어온다.
- ConsistentRead라는 매개변수를 참으로 두어서 API를 호출해야 사용할 수 있다.
- RCU를 두 번 소모하기 때문에 더 비용이 비싸다. 물론 지연시간도
DynamoDB - RCU
- 읽기 용량 유닛은 초당 크기가 4KB인 아이템을 올릴 수 있다.
- 강력한 일관된 읽기 모드라면 초당 4KB 읽기 가능
- 그냥 읽기 모드라면 초덩 8KB를 읽을 수 있다.
- 예를 들어, 10 개의 강력한 일관된 읽기 모드 요청이 들어왔고 아이템 별 사이즈는 4KB 이다.
- 즉, 40KB 인데 강력한 일관된 읽기 모드이므로 10RCU가 필요하다.
- 예를 들어, 16개의 최종 그냥 읽기 모드 요청이 들어왔고 아이템 별 사이즈는 12KB라면
- 192KB가 나오고 초당 8KB를 읽을 수 있으므로, 24 RCU가 필요하다.
- 마지막으로, 이것도 반올림이 필요하다.
- 만약, 10 개의 강력한 일관된 읽기 모드에서 아이템 별 사이즈가 6KB라면
- 초당 4KB를 읽을 수 있으므로, 아이템당 1.5 RCU 즉 2RCU가 되어, 20RCU가 필요해진다.=
DynamoDB - Partitions Internal
- 다이나모 디비는 테이블로 구성되고, 테이블에는 파티션이 존재한다.
- 파티션은 데이터의 복사본으로 특정 서버에 존재한다.
- 애플리케이션이 다이나모 디비에 뭔가를 쓸 때, 애플리케이션은 키와 속성을 보낼 것이다.
- 여기서 파티션 키로, 해싱 알고리즘을 거쳐 어느 파티션에 저장되어야 할지를 판단할 수 있다.
- 이와 같은 방식으로, 각 파티션별로 즉 서버 별로 데이터가 적절하게 분배되어 저장된다.
- 만약 10개의 파티션이 존재하고, 10개의 WCU, RCU가 들어왔다면
- 각 파티션 별로 1개의 WCU, RCU가 적절하게 분배된다는 것만 알면 된다.
DynamoDB - Throttling
- 파티션 레벨에서, WCU, RCU의 초과가 일어나면 프로비저닝 처리량 초과 예외가 발생한다.
- 하나의 파티션 키가, 핫키여서 해당 파티션에 많은 부하가 쏠릴 수 있다.
- 핫 키 예시 말고도, 하나의 아이템이 너무 큰 경우에도 예외가 발생할 수 있다.
- 예외 발생 시 해결 방법
- 지수 백오프를 하는 것이다. (SDK를 사용하고 있다면, 이미 적용되어있다.)
- 파티션 키를 최대한 많이 분산 시키는 것이다.
- 하나의 파티션을 집중적으로 읽어서 RCU이슈가 생긴 상황이라면 DtnamoDb Accelerator 라는 기능을 사용해야한다
R/W Capacity Modes - On demand
- 작업량에 따라, 자동으로 스케일 업 다운이 이뤄진다.
- WCU, RCU를 미리 예약할 필요 없다.
- 2.5 배 더 비싸다.
- 실제로 사용한 읽기와 쓰기에 대해 비용이 청구되기에 다른 단위가 쓰인다.
- Read Request Units (RRU) - 읽기의 처리량
- Write Request Units (WRU) - 쓰기 처리량
- 연산은 동일하나 실제 사용한 요청만을 기반으로 비용이 처리된다.
DynamoDB - Writing Data
데이터베이스에 데이터를 작성할 때 선택할 수 있는 몇 가지 모드가 존재한다.
- Plutltem
- 기본 키가 같은 항목이 있다면 새 항목으로 완전히 교체한다.
- WCU를 소모한다.
- UpdateItem
- 기존 항목의 속성을 바꾸거나, 기존 항목이 존재하지 않는다면, 새 항목을 추가한다.
- Conditional Writes
- 조건이 충족되었을 때에만, 쓰기/ 업데이트/ 삭제가 이뤄진다.
- 여러 아이템에 동시 접근하는 데 유용하다.
DynamoDB - Reading Data
- GetItem
- 기본 키를 기반으로 아이템을 가져온다.
- 기본 키는 해시 키 또는 해시 키 + 범위 키 둘 중 하나다.
- 읽어 오는 모드도 두 개가 존재한다.
- Eventually Consistent Read 모드 (default)
- Strongly Consistend Reads (more RCU)
- ProjectionExpression Api를 통해 특정 속성 몇 가지를 설정해 해당 속성 데이터만 가져올 수도 있다.
DynamoDB - Reading Data (Query)
- Query returns items based on:
- KeyConditionExpression
- 파티션 키에, = 연산자를 사용해 동일한 항목을 반환한다.
- sort 키에 등호 연산자를 사용한 항목 반환도 가능하다. (이는 선택 사항이다.)
- FilterExpression
- 쿼리 작업이 완료된 후 데이터가 반환되기 이전에 필터링을 추가한다.
- 기본 키가 아닌 속성에 필터링을 가할 수 있다.
- Limit 파라미터를 사용해 가져올 항목의 수를 제한할 수도 있다.
- 항목 수 제한에 도달하거나, 1MB에 도달할 때 강제로 반환 된다.
- 더 많은 데이터를 가져오고 싶으면 페이징 기법을 써야한다.
- 보조 인덱스를 사용 가능하다.
- KeyConditionExpression
DynamoDB - Reading Data (Scan)
- 쿼리가 특정 파티션 키 데이터를 읽어온다면, scan은 테이블 전체의 데이터를 읽어온다.
- 필터링도 가능하지만, 클라이언트 사이드에서만 된다. 즉, 효율이 좋지 못 하다.
- 스캔은 전체 데이터를 내보내는데, 최대 1Mb의 데이터만을 내보낼 수 있다.
- 마찬가지로 더 많은 데이터를 읽고 싶다면, 페이징 기술을 사용해야 한다.
- 아주 많은 양의 RCU를 사용한다.
- 따라서 다른 작업에 영향을 끼치게 하고 싶지 않으면 Limit을 스캔에 적용하거나,
결과 사이즈를 줄여햐 한다.
- 따라서 다른 작업에 영향을 끼치게 하고 싶지 않으면 Limit을 스캔에 적용하거나,
- 더 빠른 성능을 원한다면, 병렬 스캔을 사용하면 된다.
- 병렬 스캔을 통해, 여러 개의 세그먼트를 동시에 스캔한다.
- 물론 사용되는 처리량과 RCU는 늘어난다.
- ProjectionExpression, filterExpression 과 같이 사용할 수 있다.
DynamoDB - Deleting Data
- DeleteItem
- 개별 항목 삭제 시 사용하며
- 조건부 삭제도 가능하다
- Delete table
- 테이블의 모든 것을 삭제한다.
- 테이블 전체와 테이블의 항목을 삭제하며 scan을 활용한 삭제보다 속도가 빠르다
- 전부 삭제하려면 scan을 통한 삭제말고 Delete Tabla APi를 사용하도록 하자
DynamoDB - Deleting Data
- 일괄로 작업을 처리하여 API호출 수를 줄이고 효율을 높일 수 있다.
- 배치 작업에 속한 모든 작업은 다이나모 디비를 통해 병렬로 적용되어, 효율성을 높인다.
- 일부 작업이 실패할 수도 있으나, 실패한 항목이 리턴되므로, 해당 항목만 다시 시도할 수 있다.
- BatchWritenItem
- 호출 한 번으로 최대 25번의 Putltem과 DeleteItem 작업을 수행할 수 있다.
- 초당 16MB의 데이터를 기록할 수 있으며, 항목마다 400KB의 제한이 똑같이 적용된다.
- 업데이트 작업은 배치로 불가능 하다.
- 쓰기 용량이 부족한 경우, UnprcessedItems라는 것이 반환되며,
특정 항목을 다시 시도할 수 있다.- 지수 백오프 방식을 사용하던지, 실패 아이템을 받아 WCU양을 늘려 재시도를 할 수도 있다.
- BatchGetItem
- 하나 이상의 테이블에서 항목이 반환되며, 최대 100개의 항목과 16GB의 데이터를 받을 수 있다.
- 모든 항목을 병렬로 가져온다.
- 일부 항목이 누락될 경우, 용량이 부족해서 읽기 작업에 실패하고, UnprocessedKeys가
리턴되는 경우도 흐름은 똑같다. - 지수 백오프로 다시 시도하던지, 읽기 용량을 추가해 다시 시도하던지 하면 된다.
DynamoDB - PartiQl
- 특정 작업을 수행하기 위한 API 호출이 있지만, 때로는 직접 SQL을 사용해야할 때가 있다.
- PartiQl을 사용하면 SQL을 사용해서 데이터를 선택, 삽입, 업데이트, 삭제할 수 있다.
- 하지만 조인은 지원하지 않는다.
- AWS Management Console
- NoSQL Workbench
- DynamoDb APi
- AWS CLI
- AWS SDK
- 등에서 PartiQl을 사용할 수 있다.
'AWS' 카테고리의 다른 글
[AWS] aws 강의 섹션 24 - 2 (Code Deploy, Code Star, Code Artifact, code Guru) (0) | 2024.11.27 |
---|---|
[AWS] aws 강의 섹션 24 - 1 (CI/CD, Code Commit, Code Build, Code Deploy) (0) | 2024.11.20 |
[AWS] aws 강의 섹션 21-2 (람다함수, X-Ray, TMP, ECR, LIMIT) (3) | 2024.10.24 |
[AWS] aws 강의 섹션 21-1 (람다 (Lambda), 람다 함수(Labda Function)) (1) | 2024.10.22 |
[AWS] aws 강의 섹션 20-2 (X-Ray, CloudTrail) (1) | 2024.10.18 |