Database Sharding
펌: <https://nesoy.github.io/articles/2018-05/Database-Shard>
1. Partitioning
(1)배경
서비스의 크기가 점점 커지게 되면서 다양하고 많은 Table들이 존재하게 되었다.
VLDB(Very Large DBMS)전체 DB가 하나의 DBMS에 다 들어가기 힘들어지는 DBMS이 자연스럽게 등장하였고 하나의 DBMS가 많은 Table을 관리하다 보니 느려지는 이슈가 발생하게 되었다.
이러한 이슈를 해결하기 위한 하나의 방법이 바로 파티셔닝(Partitioning)이다.
(2)Partitioning이란?
- 큰 Table이나 인덱스를 관리하기 쉬운 단위로 분리하는 방법을 의미한다.
Benifits
가용성(Availability)
- 물리적인 Partitioning으로 인해 전체 데이터의 훼손 가능성이 줄어들고 데이터 가용성이 향상된다.
관리용이성(Manageability)
- 큰 Table들을 제거하여 관리를 쉽게 해준다.
성능(Performance)
- 특정 DML과 Query의 성능을 향상시킴, 주로 대용량 Data Write 환경에서 효율적이다.
- 많은 Insert가 있는 OLTP 시스템에서 Insert 작업들을 분리된 파티션들로 분산시켜 경합을 줄인다.
Disadvantages
- Table간의 Join에 대한 비용이 증가한다.
- 테이블과 인덱스를 별도로 파티션 할수는 없다. 테이블과 인덱스를 같이 Partitioning 하여야 한다.
Partitioning 범위
Range partitioning
- 연속적인 숫자나 날짜 기준으로 Partitioning 한다.
- 손쉬운 관리 기법 제공 에 따른 관리 시간의 단축할 수 있다.
- ex) 우편번호, 일별, 월별, 분기별 등 의 데이터에 적합하다.
List partitioning
- 특정 Partition에 저장 될 Data에 대한 명시적 제어 가능하다.
- 분포도가 비슷 하며, 많은 SQL에서 해당 Column의 조건이 많이 들어오는 경우 유용하다.
- Multi-Column Partition Key 제공하기 힘들다.
ex) [한국, 일본, 중국 -> 아시아] [노르웨이, 스웨덴, 핀란드 -> 북유럽]
Composite partitioning
- Composite Partition은 Partition의 Sub-Partitioning 을 말한다.
- 큰 파티션에 대한 I/O 요청을 여러 partition으로 분산할 수 있다.
- Range Partitioning 할 수 있는 Column이 있지만, Partitioning 결과 생성된 Partition이 너무 커서 효과적으로 관리할 수 없을 때 유용하다.
- Range-list, Range-Hash
Hash partitioning
- Partition Key의 Hash값에 의한 Partitioning (균등한 데이터 분할 가능)
- Select시 조건과 무관하게 병렬 Degree 제공 (질의 성능 향상)
- 특정 Data가 어느 Hash Partition에 있는지 판단 불가
- Hash Partition은 파티션을 위한 범위가 없는 데이터에 적합
(3)방법
Horizontal Partitioning
Benefits
- 데이터의 개수를 기준으로 나누어 Partitioning한다.
- 데이터의 개수가 작아지고 따라서 index의 개수도 작아지게 된다. 자연스럽게 성능은 향상된다.
Disadvantages
- 서버간의 연결과정이 많아진다.
- 데이터를 찾는 과정이 기존보다 복잡하기 때문에 latency가 증가하게 된다.
- 하나의 서버가 고장나게 되면 데이터의 무결성이 깨질 수 있다.
Vertical Partitioning
- 테이블의 컬럼을 기준으로 나누어 Partitioning한다.
- 정규화하는 과정도 이와 비슷하다고 볼 수 있지만 Vertical Partitioning은 이미 정규화된 Data를 분리하는 과정이다.
- 자주 사용하는 컬럼등을 분리시켜 성능을 향상시킬 수 있다.
Reference
- https://en.wikipedia.org/wiki/Partition_(database)
- http://theeye.pe.kr/archives/1917
- http://tnsdogfoot.blogspot.kr/2014/09/2014-9-25.html
- http://geekswithblogs.net/shaunxu/archive/2012/01/07/sql-azure-federation-ndash-introduction.aspx
- http://wiki.gurubee.net/pages/viewpage.action?pageId=3899999
출처: <https://nesoy.github.io/articles/2018-02/Database-Partitioning>
2. Sharding (샤딩)
(1)왜 샤딩(Sharding)이 필요할까요?
- 파티셔닝과 동일함으로 Link를 추가합니다. Link
Vertical Partitioning
- 도메인에 따라 쉽게 분리할 수 있습니다.
- 도메인에 영향을 많이 받기 때문에 대부분 application level에서 CRUD를 구현합니다.
(2)샤딩(Sharding)이란?
- 같은 테이블 스키마를 가진 데이터를 다수의 데이터베이스에 분산하여 저장하는 방법을 의미합니다.
- application level에서도 가능하지만 database level에서도 가능합니다.
- Horizontal Partitioning이라고 볼 수 있습니다.
(3)샤딩(Sharding)을 적용하기에 앞서.
- 샤딩(Sharding)을 적용한다는것은?
- 프로그래밍, 운영적인 복잡도는 더 높아지는 단점이 있습니다.
- 가능하면 Sharding을 피하거나 지연시킬 수 있는 방법을 찾는 것이 우선되어야 합니다.
- Scale-in
- Hardware Spec이 더 좋은 컴퓨터를 사용합니다.
- Read 부하가 크다면?
- Cache나 Database의 Replication을 적용하는 것도 하나의 방법입니다.
- Table의 일부 컬럼만 자주 사용한다면?
- Vertically Partition도 하나의 방법입니다.
- Data를 Hot, Warm, Cold Data로 분리하는 것입니다. Link
(4)샤딩(Sharding)에 필요한 원리
- 분산된 Database에서 Data를 어떻게 Read할 것인가?
- 분산된 Database에 Data를 어떻게 잘 분산시켜서 저장할 것인가?
- 분산이 잘 되지 않고, 한 쪽으로 Data가 몰리게 되면 자연스럽게 Hotspot이 되어 성능이 느려지게 됩니다.
- 그렇기 때문에 균일하게 분산하는 것이 중요한 목표입니다.
(5)샤딩(Sharding) 방법에 대해
Shard Key를 어떻게 정의하느냐에 따라 데이터를 효율적으로 분산시키는 것이 결정됩니다.
A) Hash Sharding
- Shard Key : Database id를 Hashing 하여 결정합니다.
- Hash크기는 Cluster안에 있는 Node개수로 정하게 됩니다.
- 아주 간단한 Sharding 기법입니다.
단점은 없을까요?
- Cluster가 포함하는 Node 개수를 늘려보거나 줄여보면 어떨까요?
- Hash 크기가 변하게 되고. Hash Key 또한 변하게 됩니다.
- 그러면 기존에 있던 Hash Key에 따라 분배된 Data 분산 Rule이 다 어긋나게 되고.
- 결국엔 ReSharding이 필요하게 됩니다.
- 짝수번째 Node에 큰 크기의 Data만 들어간다고 가정해보면 어떨까요?
- Hash Key로 분산되기 때문에 공간에 대한 효율은 고려하지 않았습니다.
B) Dynamic Sharding
- Naming 그대로 Dynamic으로 바꿀 수 있다.
- Locator Service를 통해 Shard Key를 얻습니다.
- Cluster가 포함하는 Node 개수를 늘려본다면?
- Locator Service에 Shard Key를 추가만 하면됩니다.
- 기존의 Data의 Shard Key는 변경이 없습니다.
- 확장에 유연한 구조입니다.
- Example
- HDFS : Name Node
- MongoDB : ConfigServer
단점은 없을까요?
- Data Relocation을 하게 된다면?
- Locator Service의 Shard Key Table도 일치시켜줘야 합니다.
- Locator가 성능을 위해 Cache하거나 Replication을 하면 어떨까요?
- 잘못된 Routing을 통해 Data를 찾지 못하고 Error가 발생합니다.
- Locator에 의존할 수 밖에 없는 단점이 있습니다.
C) Entity Group
- 위의 Hash Sharding과 Dynamic Sharding은 Key-Value 형태를 지원하기 위해 나온 방법입니다.
Key-Value가 아닌 다양한 객체들로 구성된다면 어떨까요?
- 우리는 RDBMS의 join, index, transaction을 사용함으로써 Application의 복잡도를 줄이는 효과를 얻었습니다.
- 이와 유사한 방법으로 Sharding하는 방법이 Entity Group입니다.
장점은 어떤게 있을까요?
- 하나의 물리적인 Shard에 쿼리를 진행한다면 효율적입니다.
- 하나의 Shard에서 강한 응집도를 가질 수 있습니다.
- 데이터는 자연스럽게 사용자별로 분리되어 저장됩니다.
- 사용자가 늘어남에 따라 확장성이 좋은 Partitioning입니다.
단점은 없을까요?
- cross-partition 쿼리는 single partition 쿼리보다 consistency의 보장과 성능을 잃습니다.
- 그렇기 때문에 이런 쿼리들이 자주 실행하지 않도록 만들어야 합니다.
D) Pitfall에 대해
Logical Shard는 반드시 Sigle Node안에 있어야 합니다.
- Dynamic Sharding을 진행하게 된다면 작업량을 효과적으로 줄일 수 있습니다.
- HotSpot을 찾고 Sharding을 진행합니다.
- 지속적으로 Sharding을 진행하게 된다면 가장 오른쪽 Node만 Write을 진행하게 됩니다.
- 나머지 Node들은 Read Performance가 향상하는 효과를 얻을 수 있습니다.
(6)정리하며
- Sharding을 피하는 방법을 우선 적용해보고 불가피하다면 적용하는게 좋습니다.
- 반드시 Trade-Off가 있습니다.
- Locator와 Sync해야하는 비용이 필요합니다.
- Cross-Partition Query가 발생할 경우 기존의 Query보다 느릴 수 있습니다.
Reference