들어가기 앞서
요즘 어떻게 공부를 해야 할까 고민이 많습니다. 온라인 강의를 들으면 너무 온라인 강의에 의존하는것 같고, 책을 읽자니 아무래도 온라인 강의 보다 최신 트렌드는 조금 뒤쳐지는 것 같아요. 그래도 머리박고 그냥 해야 겠죠? 네.. 이전에는 기술 세미나 영상에 대한 공부를 했다면 이번에는 책을 읽고 정리를 하려고 합니다. "가상 면접 사례로 배우는 대규모 시스템 설계 기초"는 많은 테크 회사들이 스터디를 위해 선택하는 등 평이 괜찮은 책인것 같습니다.
백엔드 개발자에게 대규모 시스템, 분산 시스템, 성능 개선에 대한 학습은 중요하다고 생각하며 이 책은 시스템 설계에 대한 내용을 다루고 있습니다. 내용이 어려운 편이 아니고 편하게 읽기 좋으니 백엔드 개발을 하시는 주니어 개발자분들이시라면 한 번 편하게 읽어 보시는 것을 추천 드립니다.
이번 포스팅은 책을 읽으며 주요 내용을 정리하는 식으로 글을 작성할 것 같습니다. 참고해주시면 감사하겠습니다.
https://www.yes24.com/Product/Goods/102819435
가상 면접 사례로 배우는 대규모 시스템 설계 기초 - 예스24
“페이스북의 뉴스 피드나 메신저, 유튜브, 구글 드라이브 같은 대규모 시스템은 어떻게 설계할까?”IT 경력자라도 느닷없이 대규모 시스템을 설계하려고 하면 막막하다고 느낄 수 있다. 특히나
www.yes24.com
1장. 사용자 수에 따른 규모 확장성
데이터 베이스
데이터베이스는 크게 관계형 데이터베이스(RDB)와 비관계형 데이터베이스(NoSQL)로 나눌 수 있습니다.
1. 관계형 데이터베이스 (RDB)
관계형 데이터베이스는 MySQL, Oracle, PostgreSQL 등과 같은 시스템을 포함합니다. 이들 시스템은 데이터를 테이블, 열, 칼럼 형태로 구조화하여 저장하며, SQL 언어를 사용해 데이터 조회와 조작을 합니다. 또한 여러 테이블의 데이터를 조인(Join) 연산을 통해 결합할 수 있습니다.
2. 비관계형 데이터베이스 (NoSQL)
비관계형 데이터베이스는 DynamoDB, HBase 등이 대표적입니다. 이들은 데이터 모델에 따라 네 가지 유형으로 구분됩니다:
- 키-값 저장소
- 그래프 저장소
- 칼럼 저장소
- 문서 저장소
비관계형 데이터베이스는 조인 연산을 지원하지 않으며, 주로 다음과 같은 상황에서 유리합니다:
- 낮은 응답 지연시간이 필요할 때
- 비정형 데이터를 처리해야 할 때 (예: JSON, XML, YAML 등)
- 대량의 데이터를 저장해야 할 때
수직적 규모 확장 vs 수평적 규모 확장
- 수직적 규모 확장 (스케일 업): 서버에 고사양 자원(CPU, 메모리 등)을 추가하여 성능을 개선하는 방법입니다. 트래픽이 적을 때는 단순하고 효과적인 선택일 수 있습니다. 하지만, 이 방법은 다음과 같은 단점이 있습니다:
- 한계가 있다: 서버에 자원을 무한정 증설할 수는 없습니다.
- 자동 복구 및 다중화가 부족하다: 서버 장애가 발생하면 서비스가 완전히 중단될 수 있습니다.
- 수평적 규모 확장 (스케일 아웃): 서버를 추가하여 성능을 확장하는 방법으로, 대규모 애플리케이션에서 더욱 적합합니다. 이 방법은 확장성과 가용성을 높이며, 장애 발생 시 서비스 중단을 최소화할 수 있습니다.
로드밸런서
웹 서버에 사용자가 몰려 서버가 한계에 다다르면 응답 속도 저하나 서버 접속 불가 문제가 발생할 수 있습니다. 이를 해결하기 위해 로드밸런서를 도입하는 것이 효과적입니다.

로드밸런서는 여러 웹 서버에 트래픽을 고르게 분산하여 성능을 향상시킵니다. 보통 로드밸런서는 공개 IP로 접속하고, 웹 서버 간 통신은 사설 IP를 사용하여 보안을 유지합니다. 로드밸런서와 두 대의 웹 서버를 함께 사용하면 가용성이 향상되고, 장애 발생 시 자동 복구가 가능합니다.
주요 이점:
- 가용성 향상: 서버 1이 다운되면 트래픽이 서버 2로 전송되어 웹사이트가 다운되지 않습니다. 서버를 추가하여 부하를 분산할 수 있습니다.
- 확장성: 웹사이트 트래픽이 증가하면 로드밸런서를 통해 서버를 추가하여 용량을 확장할 수 있습니다.
데이터베이스 다중화
많은 데이터베이스 관리 시스템(DBMS)은 다중화를 지원합니다. 보통, 주(master) 서버와 부(slave) 서버 간에 복제(Replication) 관계를 설정하여, 주 서버에서 데이터를 복사해 부 서버에 저장합니다. 이때, 쓰기 연산(insert, update, delete)은 주 서버에서만 처리되고, 읽기 연산(select)은 부 서버에서 처리됩니다. 일반적으로 읽기 연산의 비중이 더 높기 때문에, 부 서버는 주 서버보다 많습니다.

데이터베이스 다중화의 장점:
- 성능 향상: 읽기와 쓰기 연산을 분리하여 병렬 처리할 수 있어 쿼리 수가 증가하고 성능이 개선됩니다.
- 안정성: 일부 데이터베이스가 장애를 일으켜도 데이터는 여전히 보존됩니다.
- 가용성: 데이터베이스에 장애가 발생해도 다른 서버로 서비스가 계속 제공됩니다.
장애 상황에서의 가용성 보장:
- 부 서버가 다운되면: 읽기 연산은 한시적으로 주 서버가 담당합니다. 이후, 새로운 부 서버가 장애 서버를 대체하여 복구됩니다. 부 서버가 여러 대일 경우, 읽기 연산은 나머지 부 서버들로 분산됩니다.
- 주 서버가 다운되면: 만약 부 서버가 한 대만 있을 경우, 그 부 서버가 새로운 주 서버로 승격됩니다. 그러나 주 서버에서 부 서버로 승격된 데이터베이스는 최신 상태가 아닐 수 있어, 부족한 데이터는 복구 스크립트를 사용하여 복원해야 합니다. 이 문제를 해결하려면 다중 마스터나 원형 다중화를 활용할 수 있습니다.
캐시 (Cache)
캐시는 값비싼 연산 결과나 자주 참조되는 데이터를 메모리에 저장하여 빠르게 처리할 수 있게 해주는 저장소입니다. 데이터베이스 호출 빈도를 줄여 성능을 개선하고, 응답 시간을 단축시킬 수 있습니다. 캐시 계층을 추가하면 성능 향상, 데이터베이스 부하 감소, 독립적인 확장이 가능해집니다.
캐시 사용의 장점
- 데이터베이스 호출 빈도가 높을 경우, 캐시를 사용하면 성능을 크게 향상시킬 수 있습니다.
- 캐시 계층을 추가함으로써 데이터베이스의 부하를 줄일 수 있습니다.
- 캐시 서버의 규모는 독립적으로 확장 가능하여 성능을 유연하게 조정할 수 있습니다.
캐시 사용 시 유의사항
- 자주 참조되는 데이터: 캐시는 자주 참조되는 데이터를 저장할 때 효과적입니다. 자주 갱신되는 데이터보다는 빈번히 참조되지만 갱신이 드문 데이터가 캐시에 적합합니다.
- 휘발성 메모리: 캐시는 휘발성 메모리(주로 RAM)에 저장됩니다. 따라서 캐시 서버가 재시작되면 캐시된 데이터는 사라집니다. 영속적인 데이터는 캐시에 두지 않고, 지속적 저장소(예: 데이터베이스)에 보관해야 합니다.
- 캐시 만료 기한: 캐시의 만료 기한을 설정할 때 주의가 필요합니다. 너무 짧으면 데이터베이스를 자주 조회하게 되고, 너무 길면 원본 데이터와 차이가 생길 수 있습니다. 적절한 만료 시간 설정이 중요합니다.
- 일관성 문제: 캐시와 원본 데이터 간의 일관성이 중요합니다. 캐시를 갱신하는 작업과 데이터베이스를 갱신하는 작업이 단일 트랜잭션으로 처리되지 않으면 일관성이 깨질 수 있습니다. 이를 해결하기 위한 전략이 필요합니다.
- 단일 장애 지점: 캐시 서버가 하나일 경우 단일 장애 지점(SPOF)가 될 수 있습니다. 따라서 분산 캐시를 사용하여 장애를 예방해야 합니다.
- 캐시 메모리 용량: 캐시 메모리가 너무 작으면, 자주 캐시에서 밀려나 성능이 저하될 수 있습니다. 따라서 충분한 메모리를 할당하여 예기치 못한 데이터 증가에 대응해야 합니다.
- 데이터 방출 (Eviction): 캐시가 가득 차면 오래되거나 불필요한 데이터를 내보내야 합니다. 일반적인 방출 정책은 다음과 같습니다:
- LRU (Least Recently Used): 마지막으로 사용된 지 오래된 데이터를 내보냄.
- LFU (Least Frequently Used): 사용 빈도가 낮은 데이터를 내보냄.
- FIFO (First In, First Out): 가장 먼저 들어온 데이터를 가장 먼저 내보냄.
CDN (Content Delivery Network)
CDN은 정적 콘텐츠(이미지, 비디오, CSS, JavaScript 파일 등)를 지리적으로 분산된 서버 네트워크를 통해 전송하는 기술입니다. 사용자는 가장 가까운 CDN 서버에서 콘텐츠를 받게 되며, 서버와의 물리적 거리나 네트워크 상황에 따라 웹사이트 로딩 속도가 달라집니다.
CDN 사용 시 고려할 사항
- 비용 문제: CDN은 제3자 사업자가 운영하며, 데이터 전송량에 따라 요금이 부과됩니다. 자주 사용되지 않는 콘텐츠는 CDN에서 캐시하면 오히려 비효율적일 수 있기 때문에 효율적인 캐싱 전략이 필요합니다.
- 캐시 만료 시간: 캐시의 만료 시간을 적절하게 설정하는 것이 중요합니다. 너무 짧거나 너무 길게 설정하면 캐시 효율이 떨어질 수 있습니다. 적절한 만료 시간을 설정해 콘텐츠를 최적화해야 합니다.
- CDN 장애 대비: CDN 서비스에 장애가 발생할 수 있으므로, 장애 발생 시 대처 방안을 마련해야 합니다. 예를 들어, CDN 서버가 다운되면 원본 서버에서 콘텐츠를 가져오도록 클라이언트 측 처리를 고려해야 합니다.
- 콘텐츠 무효화: 만료되지 않은 콘텐츠라도 필요에 따라 무효화할 수 있어야 합니다. 대부분의 CDN 제공업체는 이를 위해 API를 제공하며, 이를 통해 콘텐츠를 수동으로 갱신할 수 있습니다.
무상태(stateless) 웹 계층

웹 계층을 수평적으로 확장하려면, 사용자 세션 데이터와 같은 상태 정보를 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고 필요할 때 이를 가져올 수 있도록 해야 합니다. 이 방식은 웹 서버에서 상태 정보를 제거하고, 상태 데이터를 별도의 저장소에서 관리함으로써 웹 계층의 확장성을 높여줍니다.
고정 세션 문제
웹 서버는 상태 정보를 유지해야 하므로, 클라이언트의 요청은 항상 동일한 서버로 전달되어야 합니다. 이를 해결하기 위해 대부분의 로드밸런서는 고정 세션(sticky session) 기능을 제공합니다. 그러나 이 방식은 로드밸런서에 추가적인 부담을 주며, 서버 추가/제거가 어려워지고 장애 발생 시 문제가 복잡해질 수 있습니다.
해결책: 공유 저장소 활용
상태 정보가 필요한 경우, 이를 공유 저장소에 저장하여 각 웹 서버가 필요할 때 데이터를 가져오도록 하는 방법이 더 바람직합니다. 이 방식은 상태 정보를 웹 서버와 물리적으로 분리시키고, 시스템을 단순화, 안정성을 높이며, 규모 확장을 용이하게 합니다.
데이터 센터
다중 데이터 센터 아키텍처는 장애가 없는 상황에서 사용자가 가장 가까운 데이터 센터로 안내되는 지리적 라우팅을 사용하여 성능과 안정성을 향상시킵니다. 그러나 이를 구현하려면 여러 기술적 난제를 해결해야 합니다.
주요 기술적 과제
- 트래픽 우회
올바른 데이터 센터로 트래픽을 효과적으로 전달하는 방법을 찾아야 합니다. 이를 위해 GeoDNS와 같은 기술이 사용됩니다. GeoDNS는 사용자의 위치를 기반으로 가장 적합한 데이터 센터로 요청을 라우팅하는 역할을 합니다. - 데이터 동기화
여러 데이터 센터에서 각각 독립적인 데이터베이스를 사용할 경우, 장애가 발생하고 트래픽이 다른 데이터 센터로 우회되면, 해당 데이터 센터에서 필요한 데이터를 찾을 수 없는 상황이 발생할 수 있습니다. 이를 해결하려면 데이터 다중화가 필요하며, 데이터를 여러 데이터 센터에 동기화하여 장애 발생 시에도 데이터 손실 없이 서비스를 유지할 수 있습니다. - 테스트 및 배포
다중 데이터 센터 환경에서는 자동화된 배포 도구를 활용해 모든 데이터 센터에 동일한 서비스가 설치되도록 해야 합니다. 이는 서비스의 일관성을 보장하고, 각 데이터 센터에서 동일한 환경을 유지하는 데 중요합니다.
메세지 큐
시스템을 대규모로 확장하기 위해서는 컴포넌트를 분리하고 각기 독립적으로 확장 가능하도록 설계해야 합니다. 이 과정에서 메시지 큐는 분산 시스템 문제를 해결하는 핵심 전략 중 하나로 활용됩니다.
메시지 큐는 메시지의 무손실을 보장하는 비동기 통신을 지원하는 컴포넌트입니다. 이를 통해 서버 간 결합도를 낮추고 안정적으로 확장 가능한 애플리케이션 구성이 가능합니다.
- 생산자는 소비자 프로세스가 다운된 상태에서도 메시지를 발행할 수 있습니다.
- 소비자는 생산자 서비스가 가용하지 않아도 메시지를 수신할 수 있습니다.
이러한 특성 덕분에 메시지 큐는 확장성과 안정성을 요구하는 시스템 설계에 적합합니다.
데이터베이스의 규모 확장
데이터베이스를 확장하는 방법에는 수직적 확장(스케일 업)과 수평적 확장(스케일 아웃) 두 가지 접근법이 있습니다.
수직적 확장 (스케일 업)
기존 서버에 더 많은 고성능 자원을 추가하는 방식으로, 간단한 확장 방법입니다. 스케일 업의 예시로 스택오버플로는 2013년에 1천만 명의 사용자를 하나의 마스터 데이터베이스로 처리했습니다. 하지만 스케일 업은 여러 단점을 가지고 있습니다.
- 하드웨어 한계: 사용자가 증가하면 단일 서버로 감당하기 어려워집니다.
- 단일 장애점(SPOF): 한 서버가 장애를 일으키면 전체 시스템에 영향을 미칩니다.
- 비용 증가: 고성능 서버일수록 비용이 상승합니다.
수평적 확장 (스케일 아웃)
서버를 추가하여 성능을 높이는 방법으로, 대표적인 기술은 샤딩입니다.
샤딩은 대규모 데이터를 작은 단위(샤드)로 분할하는 기술로, 샤드 간 중복 데이터는 없으며 동일한 스키마를 사용합니다.
- 샤딩 키: 데이터를 분산시키는 기준으로, 데이터를 고르게 분할할 수 있는 키를 선택하는 것이 중요합니다.
샤딩의 단점 및 문제:
- 데이터 재샤딩 (Resharding):
- 데이터 증가 또는 불균형한 샤드 분포로 인해 특정 샤드가 과부하를 겪을 때 데이터를 재배치해야 합니다.
- 이는 안정 해시(Consistent Hashing)로 해결 가능합니다.
- 유명인사 문제 (Hotspot Key Issue):
- 특정 키에 질의가 집중되어 서버 과부하가 발생하는 문제입니다.
- 예: BTS, 카리나, 현빈 등 유명인사가 같은 샤드에 저장되면 read 연산 집중으로 과부하가 발생합니다.
- 이를 해결하려면 유명인사를 다른 샤드에 분산 저장해야 합니다.
- 조인 및 비정규화:
- 샤드로 나누면 여러 샤드에 걸친 데이터를 조인하기 어려워집니다.
- 해결책: 데이터베이스를 비정규화하여 단일 테이블에서 질의가 가능하도록 만듭니다.
마지막 정리 - 대규모 시스템 설계 원칙
- 웹 계층의 무상태화: 웹 계층은 무상태로 설계하여 확장성과 복원력을 높입니다.
- 모든 계층의 다중화: 각 계층에 다중화를 도입해 장애 발생 시에도 서비스를 지속할 수 있도록 설계합니다.
- 효율적인 데이터 캐싱: 가능한 많은 데이터를 캐시하여 시스템 성능과 응답 속도를 최적화합니다.
- 다중 데이터 센터 지원: 여러 데이터 센터를 활용해 지역 분산과 장애 대비를 강화합니다.
- 정적 콘텐츠의 CDN 활용: 정적 콘텐츠는 CDN(Content Delivery Network)을 통해 서비스하여 전송 속도를 높이고 서버 부하를 줄입니다.
- 데이터 계층의 수평 확장: 데이터 계층은 샤딩 기술을 통해 확장성을 확보하고 대규모 데이터를 효과적으로 처리합니다.
- 독립적인 서비스 분리: 각 계층은 독립된 서비스로 분할하여 유연성과 유지보수성을 향상시킵니다.
- 지속적인 모니터링 및 자동화 도구 활용: 시스템 상태를 지속적으로 모니터링하고, 자동화 도구를 활용하여 운영 효율성을 높입니다.
'기술서적으로 배우는 기술' 카테고리의 다른 글
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 11장 뉴스 피드 시스템 설계) (3) | 2025.01.16 |
|---|---|
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 10장 알림 시스템 설계) (3) | 2025.01.15 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 8장 URL 단축기 설계) (1) | 2025.01.15 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 7장 분산 시스템을 위한 유일 ID 생성기 설계) (4) | 2025.01.11 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 4장 처리율 제한 장치의 설계) (3) | 2025.01.10 |