✅ 대용량 데이터를 안정적으로 다루기 위한 기본 질문
"어떻게 하면 많은 양의 데이터를 안정적으로 삽입하고, 갱신하고, 조회할 수 있을까?"
이 질문에 답하기 위해 우리가 고려해야 할 키워드는 다음과 같다:
- 정규화: 데이터 중복을 줄이고, 관계를 명확하게 설계한다.
- 인덱스: 자주 조회되는 컬럼에 인덱스를 걸면 검색 속도가 훨씬 빨라진다.
- 트랜잭션: 데이터 변경 작업이 중간에 실패하더라도 전체 작업의 일관성을 유지하게 해준다.
- 동시성 제어: 여러 사용자가 동시에 같은 데이터를 수정할 때 충돌 없이 처리할 수 있도록 한다.
🧪 실습 환경 구축
macOS 환경에서 MySQL을 사용하는 경우, Homebrew로 간단히 설정 가능하다.
# mysql 실행
brew services start mysql
# mysql 상태 확인
brew services list
# mysql 멈추기
services stop mysql
# mysql 콘솔 접속
mysql -u root
🌐 웹의 기본 아키텍처
처음 웹 서비스를 설계할 때는 단순하게 생각할 수 있다:
클라이언트 → 서버 → 데이터베이스
하지만 서비스가 성장하면서 유저가 많아지면 서버 한 대로는 감당이 안 된다. 이때 등장하는 개념이 스케일 업과 스케일 아웃이다.
⚖️ 스케일 업 vs 스케일 아웃
스케일 업 | 스케일 아웃 | |
정의 | 서버 성능을 높임 (CPU, RAM 등 업그레이드) | 서버 수를 늘림 |
장점 | 관리가 쉬움 | 확장성이 좋고, 장애에 강함 |
단점 | 확장 한계가 있음 | 부하 분산과 장애 관리가 필요 |
예를 들어, 카페에서 바리스타 한 명이 커피를 만들고 있다면 → 스케일 업은 그 바리스타의 손을 빠르게 하는 거고, 스케일 아웃은 바리스타를 여러 명 더 고용하는 것이다.
🧠 서버는 스케일 아웃이 쉬운데, DB는 왜 어려울까?
서버는 기본적으로 ‘상태’를 갖지 않도록 설계할 수 있다. 예를 들어 로그인 상태 같은 건 보통 DB나 Redis에 저장하고, 서버 자체는 stateless하게 둔다.
하지만 데이터베이스는 데이터라는 ‘상태’를 반드시 가져야 하는 존재라서, 쉽게 나눠서 처리하기 어렵다. 그래서 DB의 스케일 아웃은 비용도 크고 구조도 복잡하다.
⚠️ 대용량 데이터/트래픽이 왜 어려운가?
- 서버 1대로는 감당 불가능 → 여러 서버, 여러 DB
- 여러 서버/DB가 동시에 일관된 데이터를 다뤄야 함
- 잘못된 코드 한 줄이 대량의 데이터에 영향을 미칠 수 있음
- 서비스 간 의존성이 복잡하게 얽혀 있음
🎯 대용량 시스템이 갖춰야 할 조건
- 고가용성 (High Availability)
언제든지 서비스가 가능해야 함 (24시간 무중단) - 확장성 (Scalability)
유저나 데이터가 늘어나도 잘 버틸 수 있어야 함 - 관측 가능성 (Observability)
문제 발생 시 원인을 빠르게 찾고, 영향 범위를 최소화할 수 있어야 함
📦 확장된 구조에서는 무엇이 추가될까?
- 로드밸런서 (예: Nginx)
- 여러 서버에 트래픽을 나눠줌
- 서버 한 대당 처리 부담을 줄여줌
- 캐시 도입 (예: Redis, Memcached)
- DB 응답이 느릴 때 캐시로 빠르게 조회
- 글로벌 캐시 vs 로컬 캐시
- 글로벌 캐시는 여러 서버가 공유
- 로컬 캐시는 각 서버 메모리에서 처리
- 만료 정책 중요 (캐시 주기, TTL 등)
- 비동기 큐 (예: RabbitMQ, Kafka)
- 대외기관 등 느린 외부 연동을 바로 처리하지 않고 큐에 넣음
- 클라이언트는 빠르게 응답받고, 실제 처리는 나중에 진행
🔁 예시 흐름 (비동기 큐)
클라이언트 요청
↓
서버에서 DB 처리 → 클라이언트에 바로 응답
↓
큐에 메시지 발행
↓
별도 워커가 외부 시스템 호출
📝 마무리
대용량 시스템은 단순히 ‘서버만 늘리면 된다’는 문제가 아니었다.
서버, DB, 캐시, 큐까지… 각각의 컴포넌트가 어떤 역할을 하고, 어떻게 연결되는지 이해해야 안정적인 시스템을 만들 수 있다.
다음엔 실제로 어떻게 인덱스를 걸고, 트랜잭션을 다루는지 MySQL 쿼리 실습 중심으로도 정리해보려고 한다.
'패스트캠퍼스 데브캠프 : 남궁성의 백엔드 개발 3기' 카테고리의 다른 글
record vs @Data, @RestController vs @Controller, @RequiredArgsConstructor, Stream, JDBC, 테스트 코드까지 실무 예제로 정리 (0) | 2025.04.29 |
---|---|
대용량 처리를 위한 MySQL 이해 | MySQL (0) | 2025.04.28 |
FastAPI 기반 챗봇 프로젝트에서 로그인 인증 및 RDB 파트 구현기 (0) | 2025.04.28 |
토이 프로젝트 3 | Fast API를 활용한 OpenAI 챗봇 개발 (RDB 파트) (0) | 2025.04.21 |
Spring DI (의존성 주입, Dependency Injection) (0) | 2025.04.01 |