문서번호 : 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 | 수정 |