복제 (Replication)
핵심 개념
하나의 DB 데이터를 여러 서버에 복사하여 읽기 성능과 가용성을 높이는 것.
[Master-Slave 구조]
Client (쓰기) → [Master]
↓ 복제
Client (읽기) → [Slave 1]
Client (읽기) → [Slave 2]
Client (읽기) → [Slave 3]
쓰기: Master만
읽기: Slave들이 분산 처리
복제 방식
| 방식 | 동작 | 장점 | 단점 |
|---|
| 동기 복제 | Slave 확인 후 커밋 | 데이터 일관성 | 느림 |
| 비동기 복제 | Master 커밋 후 전파 | 빠름 | 복제 지연 |
| 반동기 복제 | 1개 Slave 확인 후 커밋 | 균형 | 중간 성능 |
복제 지연 문제
[비동기 복제의 함정]
1. 사용자가 글 작성 (Master에 INSERT)
2. 바로 목록 조회 (Slave에서 SELECT)
3. 방금 쓴 글이 안 보임! ← 복제 지연
해결 방법:
- Write-Read: 쓰기 직후 Master에서 읽기
- 스티키 세션: 최근 쓴 유저는 Master로
- 지연 허용: "잠시 후 반영됩니다" 안내
실무 구성 패턴
[읽기 80% 서비스 - 대부분의 웹]
Master (1대) + Slave (2~3대)
→ 읽기를 Slave로 분산
[고가용성 (HA)]
Master + Standby (동기 복제)
→ Master 장애 시 Standby가 승격
→ 다운타임 최소화
[지역 분산]
서울 Master
도쿄 Slave, 미국 Slave
→ 각 지역에서 빠른 읽기
샤딩 vs 복제
복제: 같은 데이터 여러 곳에
→ 읽기 확장, 가용성 향상
샤딩: 다른 데이터 여러 곳에
→ 쓰기 확장, 용량 확장
실무에서는 둘 다 함께 사용:
Master(샤드1) → Slave(샤드1)
Master(샤드2) → Slave(샤드2)
Q.Master-Slave 복제에서 복제 지연 문제는 어떻게 해결하나요?
쓰기 직후 읽기가 옛 값을 보는 문제입니다. 상황별로 다르게 처리합니다.
| 방법 | 내용 | 대가 |
|---|
| 쓰기 직후 읽기는 리더로 | 방금 쓴 사용자만 리더에서 읽는다 | 리더 부하가 는다 |
| 세션 고정 | 일정 시간 동안 그 사용자를 리더로 | 구현이 단순하다 |
| 복제 위치 확인 | 쓰기 시점의 위치를 기억했다가 복제본이 따라잡았는지 확인 | 정확하지만 구현이 복잡하다 |
| 화면에서 흡수 | 방금 쓴 값을 클라이언트가 그대로 보여준다 | 서버 부하가 없다. 새로고침하면 드러난다 |
먼저 지연 자체를 줄이는 것도 봅니다. 긴 트랜잭션, 큰 배치 작업, 복제본의 사양 부족이 흔한 원인입니다.
지연을 지표로 감시하는 것이 기본입니다. 몇 초를 넘으면 그 복제본을 읽기 대상에서 빼는 장치도 흔합니다.
흔한 실수: 모든 읽기를 리더로 돌려 해결하는 것. 복제본을 둔 이유가 사라집니다. 정합성이 필요한 경로만 좁혀 지정해야 합니다.
Q.동기 복제와 비동기 복제의 트레이드오프를 설명해주세요
| 항목 | 동기 | 비동기 |
|---|
| 커밋 시점 | 복제본이 받았다고 확인한 뒤 | 리더에 쓰면 바로 |
| 지연 | 복제본까지의 왕복이 더해진다 | 없다 |
| 장애 시 유실 | 없다 | 아직 복제 안 된 부분이 유실될 수 있다 |
| 가용성 | 복제본이 느리면 쓰기가 함께 느려진다 | 복제본 상태와 무관 |
절충안이 준동기입니다. 복제본 중 하나만 받았다고 확인하면 커밋하는 방식으로, 유실 위험을 크게 줄이면서 지연을 제한합니다.
선택 기준은 한 건의 유실이 얼마나 치명적인가입니다. 결제와 정산은 동기나 준동기, 조회수나 로그는 비동기가 맞습니다.
흔한 실수: 동기 복제를 무조건 안전하다고 답하는 것. 복제본이 응답하지 않으면 쓰기가 멈춰 전체 서비스가 내려갑니다. 안전과 가용성을 맞바꾸는 선택입니다.
Q.복제와 샤딩의 차이점은 무엇이고, 언제 각각 사용하나요?
같은 데이터를 여러 벌 두는지, 다른 데이터를 나눠 두는지가 다릅니다.
| 항목 | 복제 | 샤딩 |
|---|
| 각 노드가 갖는 것 | 전체 데이터의 사본 | 데이터의 일부 |
| 해결하는 것 | 읽기 확장, 가용성 | 쓰기 확장, 용량 |
| 쓰기 | 리더 한 곳 | 샤드마다 분산 |
| 장애 | 다른 사본이 대신한다 | 그 샤드의 데이터만 영향 |
| 복잡도 | 낮다 | 높다. 조인과 트랜잭션이 어려워진다 |
순서가 있습니다. 복제를 먼저 씁니다. 읽기가 대부분인 서비스는 복제본만으로 해결되고 운영도 단순합니다. 쓰기가 한 대의 한계를 넘을 때 샤딩을 봅니다.
둘은 함께 씁니다. 각 샤드를 다시 복제해 샤드별로 읽기 확장과 가용성을 확보하는 구성이 일반적입니다.
흔한 실수: 둘을 대안 관계로 답하는 것. 해결하는 문제가 달라 함께 쓰는 것이 보통입니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
데이터베이스 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.