샤드와 샤딩 (Shard and Sharding)

 

샤드 (Shard: Database Architecture)

데이터베이스 샤드는 데이터베이스 혹은 검색엔진의 수평적 파티션을 말합니다. 각각의 파티션을 샤드 또는 데이터베이스 샤드라고 합니다. 각 샤드는 별도의 데이터베이스 서버 인스턴스에 분리 보관되어 로드를 분산시킵니다.

어떤 데이터는 데이터베이스의 모든 샤드에 저장되어 있지만, 어떤 데이터는 하나의 샤드안에만 존재하기도 합니다. 각 샤드는 데이터 집합의 단일 소스처럼 동작합니다.

 

샤딩 (Sharding)

Horizontal Sharding (Range based Sharding): 일반적인 샤딩을 말할때 일반적으로 수평 파티셔닝 방식을 이야기합니다. 수평 파티셔닝(Horizontal Sharding) 또는 샤딩은 스키마 복제 후 샤드키를 기준으로 데이터를 나누는것을 말합니다. 데이터베이스를 샤딩하게 되면 기존에 하나로 구성될 스키마를 다수의 복제본으로 구성하고 각각의 샤드에 어떤 데이터가 저장될지를 샤드키를 기준으로 분리합니다. DBA는 데이터 엑세스 패턴과 저장 공간 이슈(로드의 적절한 분산 , 데이터의 균등한 저장)를 고려하여 적절한 샤드키를 결정하게 됩니다.

Vertical partitioning: 수직 파티셔닝(Vertical partitioning)은 스키마를 나누고 데이터가 따라 옮겨가는것을 말합니다. 엔티티의 컬럼을 분할하는 방식입니다. 도메인에 따라 쉽게 분리 할수 있으며, 도메인의 영향을 많이 받기 때문에 어플리케이션 단에서 CRUD 구현을 합니다. 사용자 ID별, 텍스트, 사운드, 비디오 등 데이터 별로 분류할 때 많이 사용합니다. 샤딩 구현이 쉽지만 데이터가 늘어나면 추가 샤딩이 필요합니다.

 

샤딩 적용시 고려사항

DB를 운영하거나 어플리케이션은 개발하는데 있어서 일반적인 운영보다 복잡한 구조를 가지고 있습니다. 가능하면 Sharding을 하지 않고 설계하거나 구조적으로 다른 방법을 찾는 편이 좋습니다. Scale-in 하거나, Cache나 DB가 가지고 있는 자체적인 다중화 구성을 이용하는 편이 좋습니다. Table의 특정 컬럼만 자주 사용한다면, Vertical partitioning을 사용하는 편이 좋습니다. 데이터베이스의 데이터를 엑세스 빈도에 따라 Hot, Warm, Cold로 나누어 저장하는 방법도 있습니다.
Database에 데이터를 분산 저장할 때, 어느 한 노드에만 Data가 몰리면 성능 저하가 발생합니다. 균일하게 데이터를 분산하는 설계가 필요합니다.

 

샤딩의 방법

scale-out: 동일장비를 수평적으로 확장하거나 클러스터 구조를 확장합니다. Write가 빈번한 경우 별도의 데이터베이스 자체를 분할을 이용합니다. 샤드 구조에 대해 알 필요가 없고 구조 변경에 따른 수정도 필요 없습니다.

Key(Hash) based Sharding: 엔티티를 Hash 함수에 넣어 나오는 output을 기준으로 분할합니다. 특정 영역으로 데이터 값이 몰린 경우 성능 저하가 발생합니다. Hash 결과가 균등하게 분포되도록 신중한 Hash 함수 선정 필요합니다. Cluster가 포함하는 노드의 수가 증가하거나 감소하면 Hash의 크기가 변하게 되고, Hash Key 또한 변하게 됩니다. 기존에 있던 Hash Key에 따라 분배된 Data 분산 Rule이 다 어긋나게 되고, Re-Sharding 작업이 필요합니다.

Dynamic Sharding: Naming 그대로 Dynamic으로 바꿀수 있습니다. Locator Service를 통해 Shard Key를 얻습니다. 클러스터에 노드가 증가하거나 감소해도 Locator Service에 Shard Key만 추가하면 됩니다. 기존 Data의 Shard Key 변경은 없기 때문에 확장에 유연한 구조입니다. Data Relocation하게 되면 Locator Service의 Shard Key Table도 일치시켜줘야 합니다. Locator가 성능을 위해 Cache하거나 Replication을 하면 잘못된 Routing을 통해 Data를 찾지 못하고 Error가 발생합니다. Locator에 의존할 수 밖에 없는 단점이 있습니다.

Key-Value가 아닌 다양한 객체들로 구성되는 경우도 있습니다. RDBMS의 join, index, transaction을 사용함으로써 Application의 복잡도를 줄일수 있습니다. 이와 유사한 방법으로 Sharding하는 방법이 Entity Group입니다. 하나의 물리적인 Shard에 쿼리를 진행한다면 효율적입니다. 하나의 Shard에서 강한 응집도를 가질 수 있습니다. 데이터는 자연스럽게 사용자별로 분리되어 저장됩니다.사용자가 늘어남에 따라 확장성이 좋은 Partitioning입니다.
반대로 cross-partition 쿼리는 single partition 쿼리보다 consistency의 보장과 성능을 보장하지 않습니다. 그렇기 때문에 이런 쿼리들이 자주 실행하지 않도록 만들어야 합니다.

 

현재 MariaDB에서는 스파이더 엔진을 통한 RDBMS의 샤딩이 가능하며, Redis, MongoDB와 같은 NoSQL DB의 경우 샤딩을 많이 사용합니다. 오라클의 경우 18c부터 샤딩을 지원합니다. PostgreSQL의 경우도 샤딩을 지원합니다.

Line 엔지니어링에서 네이버가 자체 개발한 NBASE라는 Redis를 개량한 솔루션을 통해 MariaDB의 innodb 엔진을 사용한 샤딩을 포스팅 하고 있습니다. 해당 내용은 아래 블로그 링크를 통해 확인해 보실수 있습니다.

https://engineering.linecorp.com/ko/blog/line-manga-server-side/

https://engineering.linecorp.com/ko/blog/line-manga-database/

소셜 미디어로 공유하기

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.

 

새 블로그로 이사갑니다.

 

rastalion.dev

 

도메인 변경했어요. 현재 지속적으로 개선 중입니다.

 

This will close in 10 seconds