Programming Language

[DB] Sharding

wakelight23 2025. 1. 6. 20:36

Sharding : 조각내다

● 작은 접속자로 시작했던 DB가 이제는 1000, 2000명이 접속하는 서버로 성장했는데
   동시 접속에 대한 처리를 하지 않아서 DB가 살려달라고 하는 중...

   어떻게 해결해야 할까?

 

Sharding, 대규모 데이터베이스나 네트워크 시스템을 효율적으로 관리하고 성능을 향상하기
   위해 데이터를 여러 개의 작은 조각(=Shard)으로 나누어 분산 저장하는 기술

  → 데이터베이스에서는 물리적으로 쪼개는 기술.

  → 하나의 서버 데이터를 하나의 데이터베이스에서 관리하는 것이 아닌 여러 데이터베이스에서 관리

 

● 수평적 샤딩(Horizontal Sharding)

물리적으로 DB를 늘린다!

 

  - DB 한 개만 있을 경우에는 id가 1, 2, 3, 4, 5... 1000 한 곳에 전부 저장되었다면

  - 4개로 나누었으므로 DB1 : 1, 5, 9 ..., DB2 : 2, 6, 10..., DB3 : 3, 7, 11... DB4 : 4, 8, 12... 분산

  - 혹은 범위 기반 Sharding도 가능

if (playerId >= 1 && playerId <= 1000) {
    return 0;
} else if (playerId >= 1001 && playerId <= 2000) {
    return 1;
}
...

 - DB1 : ID 1~1000, DB2 : 1001~2000...

 

DB를 Sharding 하면 처리 속도 빠르고 좋겠네?

Sharding은 물리적으로 서버를 늘리는 것이기 때문에 현실적인 비용 문제가 생길 수 있다.

 

● 줄어드는 상황도 올 수 있는데 4개에서 3개가 되었을 때 나누어져 있던 데이터들 어떻게 처리해야 하는가

  - id & 4 일 때 1, 5, 9... / 2, 6, 10... / 3, 7, 11... / 4, 8, 12... 4씩 늘어나던 DB가 갑작스레 3개로 줄어들어서
    새로운 Shard 규칙이 적용되기에 재분배가 이루어지지 않는다면 id가 충돌.

 

  - 즉, 재분배가 이루어져야 하는데 이는 데이터 이동 비용과 시스템에 부하를 줄 수 있다.

 

● 트랜잭션 문제도 발생

  - Transaction은 하나의 데이터베이스에서만 작동이 되도록 설계

  - 분산 트랜잭션을 사용할 수 있지만 이 또한 단점이 존재

    → Transaction Manager가 존재하여 prepare, commit을 관리한다

    → 다만 DB가 최신 값으로 갱신되는 타이밍이 조금씩 다를 수밖에 없다.

    → 심지어 네트워크 장애, 데이터베이스 장애로 prepare, commit 등 처리에 필요한 메시지를

         1개 이상의 DB로부터 받지 못한다면 어떻게 처리해야 하는가

    → 즉, 분산 트랜잭션은 매우 느리다

 

Sharding, DB를 나누는 것은 상황에 따라서!

● 무작정 DB를 조각을 내서 서버를 운영하는 것은 좋다고는 할 수 없다.

 

● 데이터 처리가 빠를 수는 있지만 변수 처리에 단점이 명확하다.

 

● Sharding 사용이 고민된다면 체크리스트를 작성하여 필요성을 확립해야 한다.

  □ 데이터베이스 크기가 커서 단일 서버로 처리하기 어려운가?

  □ 동시 접속자가 많아 단일 데이터베이스 서버의 커넥션 한계를 초과하는가?

  □ 현재 데이터베이스 성능이 부족하여 응답 시간이 길거나 처리 속도가 느린가?

  □ 복잡한 샤드 관리와 모니터링을 처리할 수 있는 기술적 능력과 자원이 충분한가?

  □ 분산 트랜잭션 관리를 할 수 있는 역량이 있는가?