티스토리 뷰
발생일: 2021.03.09
키워드: DynamoDB, 다이나모디비, Partition Key, Sort Key, 파티션키, 정렬키, PK, SK, GSI
문제:
동료들이 다이나모디비의 파티션키(Partition Key)와 정렬키(Sort Key)의 관계를 헷갈려한다.
해결책:
처음엔 개념이 잘 잡히진 않았는데, 알고보니 간단하고 명확한 개념이었다.
다이나모디비로 설계하면서 자꾸 복잡하다고 느끼는 건,
설계 시점부터 스케일 아웃을 고려하고 있기 때문인 것 같다.
RDS에선 스케일을 고려했다기보단, 이름 그대로 관계(relation)에 집중해 설계했던 것 같다.
사용할 땐 쿼리를 조합하면 되니, 설계 시점엔 확장이나 호출 샘플보단 관계를 고민했다.
(다른 디비를 설계할 때에도 지금처럼 스케일을 고려해 설계했다면 어땠을까 싶다...)
여튼, 다이나모디비는 스케일 아웃에 중점을 둔 디비라는 걸 염두해두면 파티션키와 정렬키의 관계를 이해하기 쉽다.
파티션키는 물리적 공간인 파티션을 특정하는 키다.
- 스케일이 아무리 커져도 주소를 알고 있어서 빠르게 가져올 수 있다.
- 파티션키로는 일치하는 값만 가져올 수 있고, 조건문으로 작성할 수 없는 이유이기도 하다.
정렬키는 파티션 내에서 정렬하는 기준 값이다. (검색을 위한 최소의 조건이다)
- Number, Binary, String 타입을 지원한다. String 이라면 utf-8 기준으로 정렬된다.
- 단순한 (문자열) 인덱스라고 생각하면 될 듯 하다.
- 단순정렬이기 때문에 파티션의 사이즈가 커도 빠르게 가져올 수 있다. (eq, lt, gt 등의 비교 조건과 between, begin_with 만 지원한다)
이런 구조의 디비라면 빠르게 가져올 수 밖에 없을 것 같다.
대신, 제약 사항이 크고 유연하게 원하는 아이템을 조회하기 어렵다.
기본적인 조회 방법은 일치하는 파티션키를 주고, 정렬키로 특정 범위를 조회하는 것이다.
테이블에 보조 인덱스인 GSI(Global Secondary Index)를 만들면,
아이템을 조회하기 위한 또 다른 PK와 SK를 추가할 수 있다.
GSI를 만들면서 파티션키와 정렬키를 정할 수 있는데,
저장할 아이템의 속성 중 하나를 파티션키로, 다른 하나를 정렬키로 정하면 된다.
GSI을 추가하면 원본 테이블을 복제해 새로운 테이블을 만드는 방식이다.
복제한 원본 테이블의 아이템을
- GSI의 파티션키로 새로운 물리 공간을 할당해 저장하고,
- GSI의 정렬키로 정렬해 저장해둔다.
- 원본 테이블이 변경되면 GSI의 테이블도 동기화하는 구조다.
원본 테이블과 마찬가지로,
GSI도 파티션키와 정렬키로 특정 공간에 정렬돼 저장되어 있기 때문에,
원본 테이블과 동일한 성능 수준으로 조회할 수 있다.
물론, 빠른 확장과 안정적인 성능을 위해 다양한 제약이 있다.
- 아이템 하나의 크기는 400KB
- 한 번 조회할 때 최대 크기는 1MB
- 배치로 가져올 때에도, 최대 100개, 16MB까지
- 배치로 쓸 때에도, 최대 25개, 16MB까지
위 내용과 관련해 좀 더 자세한 내용은 아래 키워드로 검색해보면 된다.
- DynamoDB Stream
- GSI Sparse Index
- Eventual, Strong Consistent
- Hot Partition
제약 사항이 많아서 설계 과정이 어렵긴 하지만,
구조를 알고 나니 스케일 확장에도 성능은 걱정되지 않는다. :D