채킹 내역 저장을 위한 키 설계
DynamoDB의 기술적 구현방식을 다루기보단, DynamoDB를에 대해서 얇고 넓게 소개하고, Cloudy의 채팅 내역 저장 시스템에 어떻게 적용했는지 사례를 공유합니다. 기술적 내용에 대해 자세히 알고 싶다면 하단 참고 자료에 관련 링크들을 참조해주세요
아래와 같은 키워드가 등장합니다. 본문에서 개념에 대해 설명하며 진행할 예정이나, 관련 배경지식이 있다면 더 쉽게 이해할 수 있습니다.
Dynamo Db에서는 Partiion Key와 Sort Key를 합쳐 Primary Key로 사용하는 매우 독특한 특징이 있습니다. 올바르게 Dynamo DB를 사용하기 위해서 DynamoDB의 특징과 성질을 알아보겠습니다.
Partition Key
pk는 많은 파티션 중 내가 찾고자하는 데이터가 어느 파티션에 있는지 알려주는 키입니다. 항상 equal 연산자만 사용할 수 있습니다.
Sort Key
sk를 이용해서 1:n 관계의 모델링을 적용할 수 있습니다. 오름차순, 내림차순 대로 데이터를 정렬하여 조회할 수 있습니다. begins with
, 등호 연산자 및 범위 연산자를 사용할 수 있습니다.
pk와 sk를 합쳐 Primary Key가 됩니다. 오직 Primary key로만 데이터 검색이 가능하기 때문에 pk와 sk 조합을 잘 설계해야합니다.
데이터끼리 관계를 맺는 RDBMS는 수평적 확장이 매우 힘듭니다. 때문에 주로 스케일 업을 이용하여 해결합니다. 하지만 태생이 대규모 데이터를 처리하기 위해 나온 NoSQL의 경우 무한히 스케일 아웃을 진행할 수 있습니다.
즉, NoSQL을 활용하는 데이터는 수평으로 확장 가능한 데이터가 되게끔 설계해야합니다. 또한 어느 한쪽의 인스턴스로만 트래픽이 쏠리지 않도록 키를 잘 설계해야합니다.
논리적 단위인 테이블은 한 개여도, 내부에서는 파티션이라는 단위로 쪼개져 저장됩니다.
하나의 파티션은 다음과 같은 제약사항을 가집니다. 데이터가 계속해서 늘어나더라도 파티션의 개수 증가하는 개념이지, 한 파티션 내의 제약사항은 절대로 변하지 않습니다.
Dynamo DB는 Id를 해쉬값으로 변경하여 저장되는 파티션을 결정합니다. Application 구현시 Key값을 해쉬로 변경하는 로직은 짜지 않아도 괜찮습니다.
Amazon DynamoDB에서 파티션은 데이터의 양과 테이블에 대한 읽기/쓰기 요청의 양에 따라 자동으로 관리됩니다. 파티션이 늘어나는 주요 시점은 다음과 같습니다:
1.데이터의 양이 증가할 때:
- DynamoDB 테이블에 저장된 데이터의 양이 파티션당 최대 저장 용량(10GB)을 초과할 때 새로운 파티션이 자동으로 추가됩니다. 즉, 테이블에 있는 데이터의 총량이 증가하여 각 파티션의 용량이 초과될 경우 DynamoDB는 추가 파티션을 생성하여 데이터를 분산 저장합니다.
2.프로비저닝된 읽기/쓰기 용량이 증가할 때:
- 테이블의 프로비저닝된 읽기 및 쓰기 용량 단위가 증가하면 DynamoDB는 이를 수용하기 위해 파티션 수를 늘릴 수 있습니다. 파티션당 최대 처리량(읽기/쓰기 용량)이 제한되어 있기 때문에, 필요한 처리량을 제공하기 위해 더 많은 파티션을 생성합니다.
3.온디맨드 모드에서의 스케일링:
- DynamoDB 테이블이 온디맨드 모드로 설정되어 있으면, 읽기 및 쓰기 요청의 트래픽 패턴을 자동으로 감지하여 파티션을 조정합니다. 트래픽이 급증하거나 감소할 때 테이블의 파티션 수는 자동으로 늘어나거나 줄어들 수 있습니다.
Dynamo DB는 항상 데이터를 복제하여 저장합니다. 3개의 가용영역에 복제되며 서비스는 3개의 가용영역에서 실행됩니다.
DynamoDB는 RCU와 WCU라는 컴퓨팅 단위를 사용합니다. 일반적인 RDB와는 다르게 WCU와 RCU는 독립적으로 동작합니다.
단위명 | 프로비전드 환경 | 온디맨드 환경 |
---|---|---|
RCU (Read Capacity Unit) | 4KB/s | 4KB/req |
WCU(Write Capacity Unit) | 1KB/s | 1KB/req |
Eventually Consistent 읽기 | 8KB/s | 8KB/req |
Strongly Consistent 읽기 | 4KB/s | 4KB/req |
테이블의 전체 크기를 의미합니다. 테이블에 넣을 수 있는 아이템의 개수로 따지는 것이 아닌 최대 크기로 따집니다. 400KB까지 사용 가능합니다. 하지만 400KB를 전부 사용하는 것은 권장하지 않습니다. DynamoDB는 하나의 아이템에서 한 글자만 바뀌어도 다시 쓰는 특성을 갖습니다. 이러한 이유로 아이템의 사이즈는 작게, 아이템의 개수가 많게끔 저장되는 데이터를 모델링하는 것이 이상적입니다.
-> DynamoDB의 컨셉은 무한하게 많은 데이터 중 PK+SK의 조합으로 특정한 데이터를 가능한한 빠르게 반환하는 것임을 잊지말아야합니다.
기본적으로 Dynamo DB에서는 데이터를 읽기 위한 REST API를 제공합니다.
LastEvaluatedKey
Dynamo DB에서는 페이지네이션과 비슷하게 동작합니다.
사용예시
Amazon DynamoDB에서 LSI(Local Secondary Index)와 GSI(Global Secondary Index)는 테이블의 쿼리 성능을 향상시키기 위해 사용되는 인덱스입니다. 두 인덱스 모두 테이블의 속성을 기준으로 데이터를 효율적으로 검색할 수 있게 해주지만, 사용 방법과 동작 방식에서 몇 가지 중요한 차이점이 있습니다.
일반적으로 사용을 권장하지 않습니다.
| GSI | LSI |
---|---|---|
자유도 | 생성과 삭제가 자유롭다 | 테이블 생성 시에만 생성 후, 삭제할 수 없다. |
단위처리량 | 베이스 테이블과 별도의 WCU/RCU를 갖는다. | 베이스 테이블과 WCU/RCU를 공유한다. |
제약사항 | 없다 | 10GB이하 |
개수 | 20 | 5 |
고려 | 강력한 일관성을 보장하지 않습니다. | 강력한 일관성을 보장합니다. |
rdbms에서 처럼 엔티티별로 테이블을 만들지 말자
오른쪽 예시처럼 최대한 빠르게 데이터를 조회하게 끔 해야한다.
Dynamodb가 가장 잘하는 것은 무한대의 가까운 item에서 특정개수의 아이템을 Primary Key(PK+SK)로 빠르게 조회하는 것 이다. 대량의 벌크성 쿼리, range 쿼리, 집계 쿼리는 잘 수행하지 못합니다.
사이즈가 작은 여러개의 테이블보다는 사이즈가 큰 하나의 테이블을 사용하는 것이 낫다.
DynamoDB는 테이블 단위 완전 관리형 서비스이다.
Dynamo DB는 풀서버리스 형태의 테이블 단위 완전관리형 서비스입니다. 여러 개의 테이블을 만들게 되면 각 테이블에 대한 설정, 모니터링, 최적화 등의 관리 작업이 필요하게 됩니다. 예를 들어 각 테이블의 스키마 설정 및 변경, 인덱스 관리, 성능 모니터링 및 튜닝, 읽기/쓰기 용량 설정 등을 각각의 테이블 별로 따로 해줘야합니다.
이는 완전관리형 서비스의 설계 철학, 즉 "사용자가 최소한의 관리만으로 데이터베이스를 운영할 수 있도록 한다"는 목표에 어긋나게 됩니다.
테이블을 하나로 사용해야지, 여러개의 파티션을 사용하는 DynamoDB의 특성을 제대로 활용할 수 있습니다. 또한 핫 파티션이 발생할 확률이 줄어듭니다.
OLTP vs OLAP
OLTP가 적합합니다. OLAP인 경우 DynamoDB 외부로 파이프라인을 만들어 분석을 수행해야합니다.
디자인 패턴
비정규화