데이터베이스 샤딩이란 무엇인가요?

데이터베이스 샤딩은 대량의 데이터를 보유한 애플리케이션의 확장성 문제를 해결하는 데 사용되는 전략입니다. 샤딩은 대규모 단일 논리적 데이터 세트를 샤드라고 하는 더 작고 관리하기 쉬운 부분으로 분할하는 작업입니다. 각 샤드는 별도의 데이터베이스 서버 인스턴스에 저장되어 데이터와 워크로드가 여러 머신에 효과적으로 분산됩니다.

샤딩은 수평 확장을 위한 핵심적인 방법입니다. 결국 하드웨어 한계에 도달하는 단일 서버를 더 많은 CPU 또는 RAM(수직 확장)으로 업그레이드하는 대신 샤딩을 사용하면 클러스터에 더 많은 상용 서버를 추가할 수 있습니다. 이를 통해 애플리케이션은 데이터 볼륨과 사용자 트래픽의 거의 무한한 증가를 처리할 수 있습니다.

Credit Karma의 데이터베이스 혁신: 샤딩된 MySQL에서 Spanner로

샤딩은 수평 확장하는 강력한 방법이지만, 세 가지 일반적인 수평 확장 전략 중 하나입니다.

  • 읽기 복제본: 읽기 전용 트래픽을 처리하기 위해 기본 데이터베이스의 사본을 만들어 기본 서버의 부하를 줄입니다.
  • 샤딩: 데이터와 쓰기 트래픽을 여러 독립 서버에 분산합니다.
  • 분산 데이터베이스: Spanner와 같은 제품은 데이터베이스 엔진 자체 내에서 분산과 확장을 기본적으로 처리하므로 수동 샤딩이 필요하지 않습니다.

데이터베이스 샤딩은 어떻게 작동하나요?

데이터베이스 샤딩은 샤드 키라는 특정 값을 기준으로 데이터를 그룹화하여 작동합니다. 샤드 키는 데이터베이스의 열(예: 사용자 ID, 고객 지역, 주문 번호)로, 특정 데이터 행을 저장할 서버를 결정합니다. 데이터가 데이터베이스에 기록되면 시스템은 이 키를 보고 데이터가 어디에 속하는지 결정합니다.

나중에 데이터를 찾기 위해서는 시스템이 쿼리를 올바른 위치로 라우팅해야 합니다. 이 라우팅은 주로 다음 두 가지 방식으로 이루어집니다.

  • 라우팅 레이어: 샤딩 아키텍처는 스마트 부하 분산기 또는 전용 프록시 레이어를 사용할 수 있습니다. 애플리케이션이 쿼리를 전송하면 라우팅 레이어가 샤드 키를 확인하고 해당 데이터를 보유한 샤드를 계산하여 트래픽을 해당 서버로 전달합니다.
  • 애플리케이션 측 로직: 멀티플레이어 게임이나 고성능 실시간 앱과 같은 일부 경우에는 애플리케이션 코드 자체에 샤딩 로직이 포함되어 있습니다. 이 코드는 요청을 보내기 전에 올바른 샤드 위치를 계산하므로 추가 네트워크 홉을 제거하여 지연 시간을 줄일 수 있습니다.

관련 샤드만 타겟팅하여 데이터베이스가 쿼리에 더 빠르게 응답하고 수천 개의 동시 요청을 속도 저하 없이 처리합니다.

데이터 샤딩 인포그래픽

일반적인 샤딩 방법

애플리케이션마다 데이터를 분할하는 데 필요한 논리가 다릅니다. 선택한 방법에 따라 '라우팅 레이어'가 데이터를 찾는 방식이 결정됩니다.

이 방법은 샤드 키에 수학 공식(해시 함수)을 사용하여 데이터를 할당합니다. 예를 들어 시스템은 사용자 ID(mod 4)를 계산하여 사용자를 4개의 서버 중 하나에 할당할 수 있습니다.

해시 함수는 데이터를 일관되게 배포하는 데 도움이 되지만 샤드 키의 카디널리티가 높고 빈도 편향이 낮은 경우에만 균등한 배포를 보장합니다. '파인'보다 '스미스'가 1,000배 더 많이 나타나는 '성'과 같이 공통 값이 있는 샤드 키를 선택하면 해시 함수가 모든 '스미스' 레코드를 동일한 샤드로 보냅니다. 수학 공식을 사용했음에도 불구하고 '핫 샤드'가 생성됩니다.

이 방법으로는 공식이 변경되므로 새 서버를 추가하기도 어렵습니다. 이로 인해 데이터를 '다시 샤딩'하거나 새 서버 클러스터로 이동해야 하는 경우가 많습니다.

데이터는 값의 범위를 기준으로 할당됩니다. 예를 들어 사용자 ID 1~1,000을 서버 A에, 1,001~2,000을 서버 B에 배치할 수 있습니다. 이 방식은 매우 직관적이며 데이터 시퀀스(범위 쿼리)를 읽어야 하는 쿼리에 적합합니다. 단점은 '핫스팟'입니다. 모든 신규 사용자가 서버 B에 할당되면 서버 A가 유휴 상태인 동안 서버 B가 모든 작업을 수행하게 됩니다.

이 전략은 어떤 샤드에 어떤 데이터가 있는지 정확하게 추적하는 참고표(디렉터리)를 사용합니다. 수식을 변경하지 않고도 샤드 간에 데이터를 이동할 수 있으므로 가장 유연한 옵션입니다. 그러나 이 참고표는 병목 현상이 됩니다. 모든 쿼리가 먼저 디렉터리를 확인해야 하므로 지연 시간이 추가됩니다. 디렉터리가 실패하면 전체 데이터베이스에 액세스할 수 없게 됩니다.

지리적 샤딩은 사용자의 실제 위치를 기반으로 데이터를 특정 서버에 할당합니다. 예를 들어 프랑스 사용자의 데이터는 EU의 서버에 저장되고 미국 사용자의 데이터는 북미의 서버에 저장됩니다. 이를 통해 사용자의 지연 시간(속도)이 크게 줄어들고 기업이 GDPR과 같은 데이터 상주 법규를 준수하는 데 도움이 됩니다.

기능적 파티셔닝이라고도 하는 이 방법은 데이터를 행이 아닌 특성별로 분할합니다. 예를 들어 모든 '사용자 프로필' 테이블을 서버 A에 배치하고 모든 '사진 업로드' 테이블을 서버 B에 배치할 수 있습니다. 이러한 방식은 데이터를 논리적으로 정리하지만 기능적으로는 마이크로서비스 데이터 아키텍처와 유사하며, 특정 특성(예: 포토)이 단일 서버에 비해 너무 커지면 문제를 해결하지 못합니다.

데이터를 균등하게 분산하기 위해 데이터베이스 샤딩을 최적화하는 방법

샤딩에서 가장 중요한 결정은 적절한 샤드 키를 선택하는 것입니다. 잘못된 키는 데이터가 고르지 않게 분산되는 핫스팟을 유발할 수 있지만, 올바른 키는 모든 서버가 동일하게 작동하도록 보장할 수 있습니다. 이를 최적화하려면 다음 세 가지 요소를 살펴봐야 합니다.

  1. 카디널리티: 키가 가질 수 있는 고유한 값의 수를 나타냅니다. 데이터를 여러 개의 작은 청크로 분할할 수 있도록 카디널리티가 낮은 키('성별' 또는 '주' 등)가 아닌 카디널리티가 높은 키(사용자 ID 등)가 좋습니다.
  2. 빈도: 특정 값이 너무 자주 나타나는 키는 피해야 합니다. 예를 들어 '도시'별로 샤딩하고 사용자의 80%가 뉴욕에 거주하는 경우 '뉴욕' 샤드가 과부하됩니다.
  3. 단조로운 변경: 타임스탬프 또는 자동으로 증가하는 ID와 같이 시간이 지남에 따라 엄격하게 증가하는 키는 피하세요. 날짜별로 샤딩하면 모든 새 데이터 쓰기가 '오늘' 샤드로 이동하여 쓰기 핫스팟이 발생하고 이전 샤드는 유휴 상태로 유지됩니다.

주요 샤딩 관련 용어

이러한 용어는 시스템 설계에서 종종 함께 사용되지만 서로 다른 문제를 해결합니다.

샤딩은 데이터 조각이 완전히 다른 서버에 분산되는 수평 파티셔닝의 한 유형입니다. 이렇게 하면 서로 다른 서버가 동시에 쓰기를 처리할 수 있으므로 하드웨어 용량 한도(스토리지)와 쓰기 처리량 병목 현상이 모두 해결됩니다.

  • 수동 샤딩: 수동 샤딩 환경에서는 개발자 또는 데이터베이스 관리자가 샤드 키를 정의하고, 각 샤드에 대한 인프라를 만들고, 쿼리를 라우팅하는 로직을 작성해야 합니다. 이를 통해 데이터가 정확히 어디에 저장되는지 세부적으로 제어할 수 있습니다. 하지만 유지보수에 상당한 노력이 필요합니다. 샤드 1개가 너무 커지면 데이터를 수동으로 '다시 샤딩'해야 하는데 이 과정에서 애플리케이션 다운타임을 최소화하면서 수백만 개의 행을 새로운 서버로 이동해야 합니다.
  • 자동 샤딩: Bigtable과 같은 NoSQL 데이터베이스나 Spanner와 같은 분산 SQL 데이터베이스에서 자주 볼 수 있는 자동 샤딩은 데이터와 트래픽의 분산을 자동으로 처리합니다. 시스템은 각 서버의 데이터 크기와 부하를 모니터링합니다. 특정 샤드가 '핫스팟'이 되거나 너무 커지면 데이터베이스 엔진이 자동으로 샤드를 분할하고 데이터를 덜 혼잡한 서버로 이동합니다. 이를 통해 팀의 운영 부담을 줄이고 애플리케이션이 확장될 때 일관된 성능을 유지할 수 있습니다.

파티셔닝은 큰 테이블을 더 작고 관리하기 쉬운 조각으로 분할(예: 로그 테이블을 월별로 분할)하지만 동일한 서버 인스턴스에 유지하는 것을 의미합니다. 이렇게 하면 테이블의 나머지 부분에 영향을 주지 않고 이전 데이터를 더 쉽게 보관처리하거나 삭제할 수 있으므로 스토리지 문제가 해결됩니다. 하지만 서버 문제를 해결하지는 못합니다. 모든 파티션이 여전히 단일 머신에 상주하므로 동일한 CPU와 RAM을 계속 공유합니다. 즉, 서버가 성능 한도에 도달하면 파티셔닝이 도움이 되지 않습니다.

복제는 전체 데이터베이스를 여러 서버에 복사하는 프로세스입니다. 읽기 가용성 측면에서 좋은 선택이 될 수 있습니다. 한 서버에 장애가 발생하면 다른 서버가 인계할 수 있습니다. 그러나 작성된 모든 데이터가 모든 복제본에 복사되어야 하므로 쓰기 속도가 단일 머신의 용량으로 제한되어 쓰기 확장에는 도움이 되지 않습니다.

또 하나 중요한 것은 대부분의 복제 모델은 한 번에 하나의 '작성자'(기본 노드)만 허용합니다. 여러 서버가 동시에 쓰기를 수락하도록 허용하려고 하면 2개의 서버가 서로 다른 정보로 동일한 레코드를 업데이트하려고 시도하는 쓰기 충돌이 발생할 위험이 있습니다. 이러한 충돌을 해결하는 것은 기술적으로 어렵고 정교한 분산 시스템으로 처리하지 않으면 데이터 손실이나 불일치로 이어질 수 있습니다.

Spanner와 같은 분산 데이터베이스는 수동 오버헤드 없이 샤딩의 이점을 제공합니다. 이러한 시스템은 처음부터 머신 클러스터 전반에 걸쳐 작동하도록 설계되었습니다. 데이터 배포, 재조정, 복제를 자동으로 투명하게 처리합니다. 이러한 시스템 중 일부에는 여러 작성자가 있으며 쓰기 충돌을 자동으로 처리합니다. 이를 통해 기존 관계형 데이터베이스의 일관성을 유지하면서 수평으로 확장할 수 있습니다.

아래 표를 참고하여 이러한 핵심 데이터베이스 개념의 차이점을 이해하세요.

기능

샤딩

파티션 나누기

복제

분산 데이터베이스

주요 목표

대규모 쓰기 확장 및 스토리지

관리 효율성 및 유지보수

고가용성 및 읽기 확장


자동화된 글로벌 확장

데이터 위치

다른 서버에 다른 데이터 청크

동일한 서버의 여러 데이터 청크

여러 서버에 동일한 데이터의 사본

클러스터 전반에서 관리

쓰기 성능

높은 개선(쓰기 동시에 발생)

약간 개선(더 작은 색인)


개선 없음(쓰기는 모든 사본으로 이동해야 함)

높은 개선

복잡성

높음

보통

낮음

낮음(관리형)

기능

샤딩

파티션 나누기

복제

분산 데이터베이스

주요 목표

대규모 쓰기 확장 및 스토리지

관리 효율성 및 유지보수

고가용성 및 읽기 확장


자동화된 글로벌 확장

데이터 위치

다른 서버에 다른 데이터 청크

동일한 서버의 여러 데이터 청크

여러 서버에 동일한 데이터의 사본

클러스터 전반에서 관리

쓰기 성능

높은 개선(쓰기 동시에 발생)

약간 개선(더 작은 색인)


개선 없음(쓰기는 모든 사본으로 이동해야 함)

높은 개선

복잡성

높음

보통

낮음

낮음(관리형)

데이터베이스 샤딩의 이점

샤딩은 테라바이트 규모의 데이터 또는 초당 수백만 건의 트랜잭션을 처리하는 애플리케이션에 유일하게 실행 가능한 솔루션인 경우가 많습니다.

수평 확장

샤딩을 사용하면 클러스터에 표준 서버를 추가하여 거의 무한대로 확장할 수 있습니다. 이렇게 하면 기존의 수직 확장 애플리케이션의 '하드웨어 세금'을 피할 수 있습니다. 샤딩이 없으면 성능 한계에 도달하는 값비싼 특수 하드웨어를 구매해야 하는 경우가 많습니다. 샤딩을 사용하면 더 저렴한 범용 머신을 사용하여 비즈니스와 함께 데이터베이스를 확장할 수 있습니다.

쿼리 성능 개선

샤딩은 각 서버가 더 작은 데이터 세트를 검색하므로 개별 쿼리 속도를 높입니다. 1억 개의 행으로 구성된 색인을 검색하는 대신 100만 개의 행으로 구성된 샤드만 검색하면 됩니다. 또한 데이터가 여러 머신에 분산되어 있으므로 여러 쿼리를 병렬로 실행하여 애플리케이션의 총 처리량을 크게 늘릴 수 있습니다.

안정성

샤딩은 장애의 '영향 범위'를 제한합니다. 샤드 1개가 실패하면 해당 샤드의 사용자에게만 영향을 미치고 나머지 앱은 온라인 상태를 유지합니다. 하지만 서버가 많아지면 관리 부담이 커집니다. 수십 개의 인스턴스에서 백업, 보안, 패치를 관리하면 단일 서버 설정에 비해 운영 복잡성이 증가합니다.

샤딩의 과제

샤딩은 대규모 요구사항을 해결하지만 상당한 기술적 및 운영적 절충이 필요합니다. 단일 인스턴스 아키텍처에서 벗어나기 전에 이러한 과제를 고려해야 합니다.

  • 데이터 핫스팟: 해시 함수를 사용하더라도 트래픽이 고르지 않으면 소수의 활성 사용자 그룹으로 인해 1개의 서버가 과부하되는 반면 다른 샤드는 활용도가 낮게 유지되는 '핫스팟'이 발생할 수 있습니다.
  • 성능 회귀: 샤드 키를 사용하지 않는 쿼리는 시스템에서 모든 서버에 걸쳐 '분산-수집'을 수행해야 합니다. 마찬가지로 샤드 간 조인은 애플리케이션이 여러 물리적 위치에서 데이터를 가져와 병합해야 하므로 컴퓨팅 비용이 많이 듭니다.
  • 운영 복잡성: 샤딩된 환경을 관리하면 일상적인 작업의 난이도가 높아집니다. 스키마 업데이트, 백업, PITR(point-in-time recovery)은 여러 독립 인스턴스에서 조정되어야 합니다.
  • 트랜잭션 일관성: 많은 샤딩된 아키텍처가 서로 다른 샤드에서 ACID 트랜잭션을 지원하는 데 어려움을 겪고 있습니다. 이로 인해 개발자는 복잡한 '부분 실패' 시나리오를 관리하거나 eventual consistency 모델에 의존해야 하는 경우가 많습니다.

Google Cloud로 비즈니스 문제 해결

신규 고객에게는 Google Cloud에서 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.

Google Cloud가 데이터베이스 샤딩을 지원하는 방식

Google Cloud는 수동 샤딩의 부담을 덜어주는 데이터베이스 솔루션을 제공하므로 인프라 관리가 아닌 애플리케이션 빌드에 집중할 수 있습니다.


다음 단계 수행

데이터베이스 한도에 대한 걱정은 이제 그만할 준비가 되셨나요?

Google Cloud