시분할(Sharding)이란 무엇인가?

카테고리

프로그래밍/소프트웨어 개발

서브카테고리

데이터 분석

대상자

- 데이터베이스 설계 및 확장성 문제 해결에 관심 있는 개발자, 시스템 아키텍트

- 중간~고급 수준의 데이터베이스 운영 지식을 가진 사용자

핵심 요약

  • 시분할(Sharding)은 데이터베이스의 수평 확장 방법으로, 데이터를 여러 서버에 분산하여 성능 향상과 고가용성 확보를 목표로 합니다.
  • 주요 이점: 수평 확장, 고가용성, 성능 개선, 고 동시성 처리. 단점: 복잡한 쿼리 관리, 재분할 작업, 일관성 유지 어려움.
  • 핵심 용어: Shard Key, 수평 확장(Horizontal Scaling), 최종 일관성(Eventual Consistency).

섹션별 세부 요약

1. 문제 상황: 스케일링의 필요성

  • 초기 단일 데이터베이스가 성능 저하로 인해 부하 발생 (예: RSVP 처리 지연, 페이지 로딩 속도 감소).
  • 데이터베이스 테이블의 과도한 읽기/쓰기 패턴, 인덱스 부하, 디스크 IOPS/CPU 사용량 제한.
  • 단일 데이터베이스 구조가 성능, 확장성, 고가용성 요구에 부적합.

2. 시분할의 정의 및 이점

  • 시분할은 데이터를 여러 셰드(Shard)로 나누어 분산 저장 (예: 사용자 ID 범위, 지역, 해시 값 기준).
  • 수평 확장 가능 (서버 추가 시 처리량 증가), 고가용성 확보 (한 셰드 실패 시 다른 셰드 영향 없음), 쿼리 성능 향상 (핫스팟(Hot Spot) 줄임).
  • 고 동시성 처리 지원 (각 셰드가 독립적으로 쿼리 처리).

3. 시분할 유형 및 전략

  • 범위 기반(Range Based): 사용자 ID 1–100 → 셰드 A, 101–200 → 셰드 B 등.
  • 지리 기반(Geo Based): 미국 사용자 → 셰드 A, 유럽 사용자 → 셰드 B.
  • 해시 기반(Hash Based): hash(user_id) % number_of_shards 계산.
  • 디렉토리 기반(Directory Based): 중앙 관리 테이블로 user_id → shard_id 매핑.
  • 특성 기반(Featured Based): 특정 특성(예: 이벤트 유형) 기준 분할.

4. 시분할의 단점 및 고려 사항

  • 운영 복잡성 증가: 모니터링, 백업, 배포 관리 어려움.
  • 데이터 관리 복잡성: 셰드 간 데이터 이동 및 재분할 작업 필요.
  • 크로스 셰드 쿼리 어려움: JOIN, 집계, 트랜잭션 처리 시 성능 저하.
  • 불균형한 부하 분배: 잘못된 셰드 키 선택 → "핫 셰드" 발생.
  • 최종 일관성 유지: 셰드 간 데이터 동기화 지연으로 인한 일관성 문제.

5. 시분할 구현 단계

  1. 데이터 및 작업량 분석: 고부하 테이블 식별 (예: users, rsvps).
  2. 셰드 키 선택: 고유성과 균형된 부하 분배를 고려 (예: user_id, location).
  3. 시분할 전략 결정: 지리 기반, 테넌트 기반 등 선택.
  4. 어플리케이션 로직 업데이트: 셰드 라우팅, 크로스 셰드 쿼리 처리.
  5. 클라이언트/서버 측 셰드 라우팅 결정: 클라이언트 측 또는 서버 측(예: AWS Aurora, MongoDB).

6. 시분할 도구 및 예제

  • 도구:

- Vitess (MySQL 시분할), MongoDB (내장 시분할), Citus (PostgreSQL 확장), ProxySQL (MySQL 라우팅).

  • 예제 코드:

```javascript

// shard-config.js

export const shardMap = {

US: {

name: 'Shard A',

connectionString: 'postgres://user:pass@shard-us.example.com/meetupdb',

},

EU: {

name: 'Shard B',

connectionString: 'postgres://user:pass@shard-eu.example.com/meetupdb',

},

};

```

```javascript

// db-router.js

import { shardMap } from './shard-config.js';

import { Client } from 'pg';

export function getShardClient(region) {

const shard = shardMap[region];

if (!shard) throw new Error(No shard found for region: ${region});

const client = new Client({ connectionString: shard.connectionString });

return client;

}

```

결론

  • 시분할은 대규모 데이터베이스 확장에 효과적이지만, 셰드 키 선택 및 재분할 전략이 필수적.
  • 지리 기반 셰드 키 사용 시, 지역별 데이터 분산으로 지연 감소 가능 (예: 미국 사용자 → 셰드 A).
  • 시분할 도구(Vitess, Citus 등) 활용을 통해 복잡성을 줄이고, 성능 향상에 집중.