Search
Duplicate

Shard Key 선정 가이드

문서번호 : 11-1813896

Document Information

최초 작성일 : 2023.12.29
최종 수정일 : 2023.01.03
이 문서는 아래 버전을 기준으로 작성되었습니다.
SinglestoreDB : 8.1

Goal

Shard Key 선정 시, 고려해야 할 부분을 알아봅시다.

Solution

1. Shard Key 정의

SingleStoreDB 는 Shared Nothing 방식의 분산 데이터베이스로 특정 테이블은 모두 최소 2개 이상의 파티션으로 분할되어 있습니다.
각각의 파티션은 SingleStoreDB 클러스터를 구성하는 노드 중 하나에 속하게 되며 일반적으로 하나의 노드에는 여러개의 파티션을 포함하고 있습니다.
Shard Key는 테이블의 데이터를 어떤 파티션에 저장할 지 결정하는 하나 이상의 컬럼을 말합니다.

2. Shard Key 목적

레퍼런스(Reference) 테이블을 제외한 모든 테이블의 데이터는 반드시 특정 파티션 하나에만 저장되어야 합니다.
Aggregator 노드에서 입력된 Shard Key 컬럼 값에 해쉬(Hash) 알고리즘을 적용하여 파티션 ID를 얻고 이 값으로 저장할 파티션을 결정합니다.
Shard key 의 주요 목적은 다음과 같습니다.
데이터 균등 배포(Even Distribution)
클러스터 전체 시스템이 자원을 균일하게 사용하므로 용량 계획이 쉬워집니다.
단일 파티션 조인(Single Partition Join)
서로 다른 파티션간의 데이터를 조인할 경우 특정 노드의 조인 대상 중간 결과가 다른 노드로 이동하는 Repartition(또는 Redistribution) 이 발생할 수 있습니다.
만일 Shard key 가 동일한 경우 같은 파티션에 조인할 모든 데이터가 존재하므로 다른 노드로 데이터가 이동하는 Repartition 이 발생하지 않게 되어 성능이 향상됩니다.
다른 데이터베이스 테이블간의 조인의 경우엔 파티션 구조가 다를 수 있으므로 Shard Key 가 동일해도 무조건 Repartition 이 수행되므로 주의하여야 합니다.

3. Shard Key 특징

테이블 당 하나의 Shard Key 만 지정할 수 있습니다.
Shard Key 는 컬럼스토어(Columnstore) 및 로우스토어(Rowstore) 테이블에 모두 적용됩니다.
레퍼런스 테이블에는 Shard Key 를 지정할 수 없습니다.
물리적으로 파티션간 데이터 변경 또는 이동이 발생할 수 있는 다음 작업은 불가능합니다.
Shard Key는 alter 명령어로 수정할 수 없습니다.
Shard Key 로 지정된 컬럼의 값은 update 명령어로 수정할 수 없습니다.
Shard Key는 Primary Key 또는 Unique Key 의 부분 집합이어야 합니다.
분산 데이터베이스의 특성 상 단일 파티션 내부에서 Unique 제약 조건을 체크할 수 있어야 하기 때문입니다.
Shard key 없이 Primary Key 만 지정한 경우 Shard Key 는 자동으로 Primary Key와 동일하게 설정됩니다.
Shard Key 값이 같은 데이터는 테이블이 달라도 동일한 파티션에 저장됩니다.
Shard Key 와 Primary Key 를 지정하지 않거나 shard key() 구문에 컬럼을 지정하지 않는 경우를 Keyless Sharding 이라고 합니다.
Keyless Sharding 의 경우 데이터는 모든 파티션에 무작위로 저장됩니다. 충분한 데이터가 저장되면 파티션 별 데이터는 거의 균등한 분포를 나타냅니다.
Keyless Sharding 은 데이터 적재 시 일반 Sharded 테이블에 비해 속도가 빠릅니다. 테이블 조회 대상이 항상 전체 범위이며 다른 대용량 테이블과 조인이 없어 repartition 염려가 없다면 Keyless Sharding 을 사용할 수 있습니다.

4. Shard Key 선택 시 고려 사항

데이터 균등 배포(Even Data Distribution)
일반적으로 Unique 컬럼을 사용하는 경우 균등하게 분산될 가능성이 높습니다.
숫자형 데이터 형식의 Primary Key 의 경우 일반적으로 Shard Key 에 적당합니다.
필요한 경우 auto increment 컬럼을 사용하는 것도 방법입니다.
텍스트 데이터 형식(예 VARCHAR, TEXT)은 Shard Key 로 선택하지 않는 편이 좋습니다.
카디날리티가 충분히 높지 않는 경우 특정 파티션으로 데이터가 집중 Skewed Partition 현상 발생 가능성이 높기 때문입니다.
단일 파티션 쿼리
단일 파티션 조인(Single Partition Join)
테이블간 조인 조건으로 각 테이블의 Shard Key 가 모두 사용되어야 합니다.
각 테이블의 Shard Key 는 컬럼 갯수 및 순서 등이 모두 동일해야 합니다.
대부분 경우, 위와 같은 조건을 만족시키기 힘들기 때문에 일반적으로는 쿼리 중간 결과 집합의 Repartition 을 감수하고 데이터를 균등하게 배포하는 것을 우선하는 것이 일반적인 가이드라인입니다.
만일 자주 조인하는 테이블이 크기가 작고, 룩업, 코드성 또는 디멘전(Dimension) 성격의 테이블이라면 레퍼런스 테이블로 생성하여 repartition 없이 조인을 수행할 수도 있습니다. (레퍼런스 테이블은 모든 노드에 복제되어 있습니다.)
단일 파티션 필터
모든 Shard Key 값을 WHERE 구문에서 Equal 조건으로 사용될 경우 하나의 파티션만을 조회에 사용할 수 있기 때문에 성능 향상이 가능합니다.
이 경우 분산 데이터베이스의 모든 노드에서 해당 쿼리를 수행하는 것이 아니라 해당 파티션이 존재하는 노드에서만 쿼리가 수행됩니다.
단일 파티션 Aggregation
일반적으로 집계함수를 사용하면 파티션 레벨에서 1차 집계를 수행하고 모든 파티션의 중간 집계 결과를 Aggregator 에서 병합하며 최종 집계를 한번 더 수행합니다.
Shard Key 로 지정된 컬럼을 모두 GROUP BY 구문에 사용하면 파티션 레벨로 수행된 집계결과를 Aggregator 에서 다시 병합할 필요없이 바로 사용할 수 있어 쿼리 수행 속도가 빨라집니다.

References

History

일자
작성자
비고
2023.12.29
wee
최초 작성
2023.01.03
jsnoh
수정