시스템 규모가 커질수록 데이터베이스(DB)는 병목 현상의 중심이 됩니다.
오늘은 성능을 극대화하기 위한 인덱스의 원리와 읽기/쓰기 최적화 기법을 정리해보 았습니다.
1. 데이터베이스 인덱스 (DB Index)
인덱스란? 방대한 양의 데이터 중에서 원하는 정보를 빠르게 찾기 위해 별도로 생성한 '색인'입니다. 책의 맨 뒤에 있는 찾아보기(Index)와 같은 역할이라고 보시면 됩니다.
동작 원리 (B-Tree) 대부분의 DB 인덱스는 B-Tree(Balanced Tree) 구조를 사용합니다. 데이터를 정렬된 상태로 유지하며, 이진 탐색과 유사하게 탐색 범위를 절반씩 줄여나가기 때문에 데이터가 많아져도 탐색 속도가 매우 빠릅니다.
- 장점 (읽기 효율): SELECT 쿼리 속도가 비약적으로 향상됩니다.
- 단점 (쓰기 저하): INSERT, UPDATE, DELETE가 발생할 때마다 인덱스도 매번 정렬하고 재구성해야 합니다. 즉, 쓰기(Create) 시간은 늘어날 수밖에 없습니다.
💡 핵심 요약: 인덱스는 "읽기를 위해 쓰기를 희생하는 도구"입니다. 따라서 조회 빈도가 높고 분포도가 좋은 컬럼에 전략적으로 설정해야 합니다.
2. 읽기 요청 최적화 (Read Replication)
데이터 조회가 많은 서비스에서는 DB를 Master(쓰기용)와 Slave(읽기 전용)로 분리하는 'Replication' 전략을 사용합니다.
**주의해야 할 점: 데이터 일관성(Consistency) 문제**
Master에 데이터가 써진 후 Slave로 복제되기까지는 미세한 복제 지연(Replication Lag)이 발생할 수 있습니다. 이때 다음과 같은 위험 상황이 발생할 수 있습니다.
- 사용자가 쓰기 요청 (Master 반영)
- 복제가 완료되기 전 사용자가 다시 읽기 요청 (Slave에서 이전 데이터 조회)
- 문제 발생: 이때 만약 캐시(Redis)를 업데이트하는 로직이 있다면, Redis에 옛날 데이터가 저장되어 한동안 사용자가 잘못된 정보를 보게 됩니다.
해결 방안:
- 중요도가 높은 데이터는 쓰기 직후에 Master에서 직접 읽도록 설정합니다.
- Cache Eviction(캐시 무효화) 전략을 정교하게 설계합니다.
3. 쓰기 요청 최적화 (Write Optimization)
사용자가 몰릴 때 DB에 직접 대량의 INSERT를 날리면 시스템이 뻗을 수 있습니다. 이를 해결하기 위해 비동기 처리 방식을 도입합니다.
메시지 큐(Message Queue) 활용 쓰기 요청이 들어오면 DB에 바로 저장하지 않고, Kafka나 RabbitMQ 같은 큐에 먼저 담습니다.
- 작동 방식:
- 어플리케이션은 큐에 데이터를 넣고 즉시 응답을 반환합니다 (빠른 응답 속도).
- 백엔드 워커(Worker)가 큐에서 데이터를 하나씩 꺼내 DB에 차근차근 저장합니다.
- 장점:
- 부하 분산: 급격한 트래픽 증가에도 DB가 터지지 않게 '완충 작용'을 합니다.
- 장애 격리: DB에 일시적인 장애가 생겨도 큐에 데이터가 남아있으므로 유실을 방지할 수 있습니다.
'Study' 카테고리의 다른 글
| [내일배움캠프 TIL] 28일차 - CQRS (1) | 2026.05.14 |
|---|---|
| [내일배움캠프 TIL] 27일차 - Saga pattern(사가 패턴) (0) | 2026.05.13 |
| [내일배움캠프 TIL] 25일차 - 캐싱 전략 (0) | 2026.05.11 |
| [내일배움캠프 TIL] 24일차 - CI, Github Actions로 CI 파이프라인 구축하기 (0) | 2026.05.08 |
| [내일배움캠프 TIL] 23일차 - Docker & Docker Compose (0) | 2026.05.07 |