Foundry
분산 시스템
중급
핵심

복제와 샤딩

데이터 확장의 두 가지 방법, 복사 vs 분할

복제는 같은 데이터를 여러 곳에 두는 것(복제 지연이 생긴다)이고, 샤딩은 다른 데이터를 나눠 두는 것(샤드 키가 핵심)입니다. 목적이 다릅니다.

복제와 샤딩

복제 (Replication)

복제는 같은 데이터를 여러 곳에 두고 샤딩은 다른 데이터를 나눠 둔다 복제. 같은 것을 여러 곳에 A B C A B C A B C 읽기를 나눈다 한 대가 죽어도 나머지가 답한다. 대신 반영이 늦을 수 있다 샤딩. 다른 것을 나눠서 A B C 저장과 쓰기를 나눈다 한 대가 죽으면 그 몫은 못 읽는다. 그래서 조각마다 복제도 한다 읽기가 부족하면 복제, 저장과 쓰기가 부족하면 샤딩이다
  • 목적: 가용성, 읽기 성능 향상
  • Master-Slave: 쓰기는 Master, 읽기는 Slave 분산
  • 복제 지연(Replication Lag) 주의

샤딩 (Sharding)

  • 목적: 데이터 분산 저장 (수평 확장)
  • 키 기반 샤딩: user_id % N
  • 범위 기반 샤딩: 날짜별 분할

복제 지연이 만드는 문제

읽기를 사본으로 보내면 방금 쓴 것이 아직 안 보이는 구간이 생깁니다. 사용자에게는 자기가 한 일이 사라진 것으로 보입니다.

대응내용
쓴 직후에는 원본에서 읽는다가장 단순하다. 그 사용자에게만 원본 부하가 간다
내가 쓴 시점보다 새로운 사본에서만 읽는다사본 부하를 유지한다. 시점을 들고 다녀야 한다
화면에서 방금 쓴 값을 그대로 보여준다서버를 안 건드린다. 다른 화면에서는 여전히 안 보인다

전체를 강하게 만들 필요가 없습니다. 그 사용자에게만 보장하면 대개 충분합니다.

샤딩은 마지막에 꺼낸다

샤딩은 되돌리기가 가장 어려운 결정입니다. 그 전에 쓸 수 있는 것을 먼저 씁니다.

읽기가 부족하다: 복제를 늘린다
같은 것을 반복해 읽는다: 캐시를 둔다
오래된 데이터가 대부분이다: 옛것을 따로 옮긴다
그래도 쓰기와 저장이 부족하다: 샤딩

샤딩 뒤에 잃는 것이 큽니다. 조각을 넘는 조인과 트랜잭션이 안 되고, 조각 수를 바꾸는 재분배가 매우 어렵습니다. 그래서 나누는 키를 고를 때 몇 년 뒤의 쏠림까지 보고 정해야 합니다.

실무 포인트

  • 복제 먼저 도입 → 그래도 부족하면 샤딩
  • 샤딩 후 크로스 샤드 조인 불가 → 설계 시 신중히
  • 리샤딩(데이터 재분배)은 매우 어려운 작업
면접에서 이렇게 나옵니다

Q.수평 확장 시 데이터를 어떻게 분배하나요?

기준을 정해 나눕니다. 무엇으로 나누는지가 나중의 문제를 결정합니다.

방식내용문제
범위id 1에서 100만은 1번 샤드최근 데이터가 한쪽에 몰린다
해시키를 해시해 나머지로 배분고르지만 범위 조회가 어렵다. 노드 추가 시 대량 이동
일관 해시원형 공간에 노드와 키를 배치노드 추가 시 이동이 적다
디렉터리매핑 표를 따로 둔다유연하지만 표가 단일 장애점
지역국가나 리전 단위규제와 지연에 유리. 편중 가능

무엇을 기준으로 삼을지가 더 중요합니다.

기준 선택판단
함께 조회되는 것을 같은 샤드에한 사용자의 주문은 한 샤드에
값이 고르게 흩어지는가특정 값에 몰리면 그 샤드만 뜨거워진다
나중에 바뀌지 않는가바뀌면 데이터를 옮겨야 한다

흔한 실수: 나머지 연산으로 나누는 것. 노드를 하나 추가하면 거의 모든 키의 위치가 바뀌어 전체 재배치가 필요합니다. 그래서 일관 해시를 씁니다.

Q.복제(Replication)와 샤딩(Sharding) 차이는?

복제는 같은 데이터를 여러 벌 두는 것이고, 샤딩은 다른 데이터를 나눠 두는 것입니다.

항목복제샤딩
목적가용성과 읽기 확장쓰기와 용량 확장
각 노드가 갖는 것전체 사본일부
노드 하나가 죽으면다른 사본으로 계속그 조각을 잃는다
늘어나는 것읽기 처리량쓰기 처리량과 저장 용량
어려운 점복제 지연, 일관성조인, 트랜잭션, 재배치

순서가 있습니다. 복제를 먼저, 샤딩은 나중에 합니다. 복제는 애플리케이션 변경이 적고, 샤딩은 쿼리와 트랜잭션 구조를 바꿔야 합니다.

그리고 실제 구성에서는 둘을 함께 씁니다. 샤드마다 복제본을 두어 조각을 잃지 않게 합니다.

흔한 실수: 읽기가 느려서 샤딩하는 것. 읽기 부하는 복제본 추가나 캐시로 해결됩니다. 샤딩이 필요한 것은 쓰기나 용량이 한 대의 한계를 넘을 때입니다.

Q.Consistent Hashing이란?

노드가 추가되거나 빠질 때 옮겨야 하는 데이터를 최소로 만드는 배분 방식입니다.

항목내용
구조해시 값을 원형 공간에 배치한다
배치노드와 키를 모두 그 원에 올린다
소속키는 시계 방향으로 만나는 첫 노드에 속한다
노드 추가그 구간의 키만 옮긴다. 전체의 일부

나머지 연산과 비교하면 차이가 뚜렷합니다.

방식노드 3대에서 4대로
해시 나머지거의 모든 키의 위치가 바뀐다
일관 해시새 노드가 맡을 구간만 옮긴다

문제가 하나 있습니다. 노드가 적으면 원 위에 고르게 퍼지지 않아 부하가 치우칩니다. 그래서 가상 노드를 씁니다. 노드 하나를 원 위 여러 지점에 올려 구간을 잘게 나누면 분포가 고르고, 노드가 빠질 때 남은 노드들이 그 부하를 나눠 받습니다.

흔한 실수: 가상 노드 없이 설명하는 것. 실제 구현은 거의 모두 가상 노드를 포함하고, 그것이 없으면 노드 하나가 빠질 때 다음 노드 하나가 두 배 부하를 받습니다.

Q.마스터-슬레이브 복제의 한계는?

한계내용
쓰기가 확장되지 않는다쓰기는 한 대로 모인다
복제 지연방금 쓴 값을 복제본에서 못 읽을 수 있다
승격이 필요하다리더가 죽으면 선출까지 쓰기가 멈춘다
유실 가능성비동기 복제면 전파 안 된 쓰기를 잃는다
분리 위험옛 리더가 살아 있으면 리더가 둘이 된다

첫 번째가 근본입니다. 복제본을 열 대 붙여도 쓰기 처리량은 그대로입니다. 쓰기가 한계면 샤딩으로 가야 합니다.

다섯 번째가 가장 위험합니다. 네트워크만 끊겨 옛 리더가 자기를 리더로 믿고 계속 쓰기를 받으면, 새 리더의 데이터와 갈라집니다. 이것을 막으려고 과반 확인이나 임기 번호 같은 장치를 둡니다.

승격 시간도 설계 항목입니다. 감지에 몇 초, 선출에 몇 초가 들면 그동안 쓰기가 실패합니다. 그 시간을 사용자에게 어떻게 보이게 할지 정해야 합니다.

흔한 실수: 복제본을 늘려 가용성이 올라간다고 답하는 것. 읽기 가용성은 오르지만 쓰기 가용성은 리더 하나에 묶여 있습니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

분산 시스템 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.