대규모 트래픽에 대처하는 방법

2025. 6. 2. 11:53·개발
반응형

 

 


 

 

서비스가 성장함에 따라 사용자 수는 급격하게 증가할 수 있다.

이런 상황에서 단일 서버 및 단일 데이터베이스만 사용하는 단순한 구조를 유지한다면, 서버의 응답 속도가 느려지고 과부하가 발생할 확률이 높으며 장애가 발생했을 때 전체 서비스가 중단되어 버린다.

어떻게 하면 대규모 트래픽에 대처할 수 있을까?

 


최적화

 

  • 코드 최적화 : 비효율적인 코드 제거
  • DB 최적화 : 인덱스, 쿼리 재구성 등을 통한 처리 속도 증진

가장 기본적으로 해야 할 조치는 성능을 최적화하는 것이다.

비효율적인 처리는 서버 부하를 높일 수 있다.

따라서, 코드 또는 쿼리를 최적화하여 처리 속도를 증가해야 한다!

 


Scale-up

 

Scale-up (수직적 확장) : 더 좋은 성능의 서버를 사용하는 것

 

수직적 확장을 통해 요청 처리를 더 빠르게 수행할 수 있다.

서버에서 고사양의 자원(더 좋은 CPU, 더 좋은 메모리)을 사용하기 때문이다.

 

와 그럼 돈만 많으면 사용자가 늘어날수록 수직적 확장만 계속 하면 되겠네요?

그렇지 않다!

수직적 확장에는 한계가 있다.

아무리 좋은 서버를 사용한다 한들, 단일 서버를 무한대로 업그레이드 할 수는 없기 때문이다.

게다가, 단일 서버에 장애가 발생하면 전체 서비스가 중단되어 버리는 위험성이 있다.

 


Scale-out

 

Scale-out (수평적 확장) : 서버의 개수를 늘리는 것

 

단일 서버를 사용하는 것은 한계가 있다?

그렇다면, 서버 개수를 늘리면 되지~

어떻게 보면 "뭐야 이게 다야?" 할 수 있지만, 대규모 트래픽 처리에서 가장 중요한 개념 중 하나이다.

 

 

다만, 서버를 여러 개 사용하려면 로드밸런서가 필수적이다.

로드 밸런서는 각각의 서버에 트래픽 부하를 고르게 분산해준다.

클라이언트는 서버에 직접 접속하는 것이 아니라, 로드밸런서의 공개 IP 주소로 접속한다.

로드밸런서와 서버 집합이 사설 IP 주소로 통신하며 요청을 처리하는 것이다.

 

이렇게 다중 서버와 로드밸런서를 사용함으로써 수평적 확장을 구현하면, 트래픽을 분산할 수 있을 뿐더러 단일 서버 장애 발생에 대처할 수 있다.

하나의 서버에 장애가 발생해도, 다른 서버들이 더 열심히 일하면 되기 때문이다.

이를 통해, 서비스 계층의 가용성이 향상된다!

 


DB 다중화

 

서버는 수평적 확장을 통해 부하가 어느정도 개선되었다.

그러나, 아직 데이터베이스는 하나만 유지하고 있는 상태이다.

하나의 DB에 작업이 몰리면 역시 과부하가 발생할 수 있다.

이를 해결하기 위해 데이터베이스 다중화를 사용할 수 있다.

 

 

대부분의 DBMS가 지원하는 다중화는 master-slave 관계를 사용한다.

데이터 원본은 주 DB, 사본은 부 DB에 저장하는 것이다.

이때, 쓰기 연산은 주 DB에서만 지원하고, 부 DB는 주 DB로부터 사본을 전달받아 읽기 연산을 지원한다.

 

대부분의 애플리케이션은 읽기 연산의 비중이 쓰기 연산보다 많다.

그렇기 때문에, 보통의 경우 부 DB의 개수가 더 많다.

 

데이터베이스의 다중화로 얻을 수 있는 이점은 다음과 같다.

  • 성능 향상 : 쿼리를 병렬로 처리하므로, 성능이 향상된다.
  • 안정성 : 서버를 지리적으로 분산시킴으로써, 서버의 일부가 파괴되어도 데이터를 보존할 수 있다.
  • 가용성 : 데이터를 여러 지역에 복제하였기 때문에, 단일 데이터베이스에 장애가 발생해도 계속 서비스를 이어나갈 수 있다.

 

참고로, 모든 부 DB에 문제가 생기면 한시적으로 읽기 연산을 주 DB에서 처리하도록 할 수 있다.

또한, 주 DB에 문제가 생기면 부 DB 중 하나가 새로운 주 DB가 되게 할 수 있다.

 


캐시

 

대규모 트래픽이 발생하는 애플리케이션의 성능은 데이터베이스 작업을 얼마나 자주 수행하느냐에 따라 크게 좌우될 수 있다.

이러한 상황에서 캐시를 사용하면 응답 속도를 향상 할 수 있다.

 

캐시는 데이터 갱신이 자주 발생하지 않지만, 참조가 빈번한 상황에 적합하다.

최신화를 위한 데이터 만료 정책을 적절히 설정하는 것이 중요하며, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다.

캐시도 여러 서버로 분산할 수 있으며, 캐시가 꽉찼을 때에 기존 데이터를 방출할 정책도 적절하게 설정해야 한다.

 


CDN (Content Delivery Network)

 

CDN : 정적 콘텐츠(이미지, 비디오, CSS, Javascript)를 전송하는데 쓰이는 지리적으로 분산된 서버 네트워크

 

클라이언트에게 가장 가까운 CDN 서버가 정적 콘텐츠를 전달하는 방식이다.

지리적으로 가까운 서버에서 응답하므로, 응답 속도를 향상할 수 있다.

 

CDN도 캐시처럼 적절한 만료 기한을 설정해야 한다.

지리적으로 분산된 서버의 데이터와 원본 데이터의 일관성이 깨질 수 있기 때문이다.

또한, CDN에 문제가 생기면 원본 서버에서 데이터를 응답할 수 있는 구조를 구성할 필요가 있다.

 


무상태 아키텍처

 

사용자의 세션과 같은 상태 정보를 관리하는 저장소는 여러 서버에서 하나로 통합하여 사용하는 것이 적절한 경우가 많다.

 

만약, 여러 서버가 각각의 세션 저장소를 관리한다고 해보자.

이를 위해 로드밸런서는 특정 클라이언트의 요청은 특정 서버에서 다루게 해야 한다. (Sticky Session)

그러나, 이러한 방식은 다음과 같은 문제가 있다.

  • 특정 서버에 트래픽이 몰릴 수 있음
  • 특정 서버에 장애가 발생할 경우, 대처 불가능
  • 로드밸런서의 부담 증가

 

이러한 상황을 막기 위해 각각의 세션 저장소가 동일한 데이터를 가질 수 있도록 세션을 다른 곳으로 복제해주는 방식도 존재한다. (Session Clustering)

그러나 이러한 방법 역시 문제가 있다.

  • 모든 서버가 동일한 세션 데이터를 가져야 하기 때문에, 많은 메모리가 필요함.
  • 세션 저장소의 데이터가 바뀔 때마다 모든 서버에 값을 입력해야 하므로, 성능 저하가 발생함

 

따라서, 상태 정보는 별도의 공유 저장소로 관리하는 무상태 아키텍처 구조를 사용하는 것이 정배이다.

상태 정보는 서버로부터 분리되어 있는 것이다.

이를 통해 단순하고, 안정적이고, 확장성 있는 구조를 가질 수 있다.

 


메시지 큐

 

시스템을 더 큰 규모로 확장하려면, 시스템의 컴포넌트를 분리하고 각각 독립적으로 확장할 수 있어야 한다.

즉, MSA 구조를 통해 컴포넌트 간의 느슨한 결합을 이룰 수 있다는 것이다.

이러한 분산 시스템에서는 메시지 큐가 많이 사용된다.

 

메시지 큐는 비동기 통신을 지원하며, 한 번 저장된 메시지는 소비자가 꺼낼 때까지 안전하게 보관되도록 메시지 무손실을 보장한다.

즉, 메시지는 발행자와 소비자 간의 메시지 버퍼 역할을 수행한다.

 

메시지 큐를 사용하면 서비스(서버) 간의 결합이 느슨해져, 규모 확장성이 보장되어야 하는 안정적인 애플리케이션을 구성하기 좋아진다.

생산자는 소비자가 다운되어 있어도 메시지를 발행할 수 있고, 소비자는 생산자가 다운되어 있어도 메시지를 수신할 수 있으므로 결함에 대한 내성도 높일 수 있다.

단, 메시지 큐는 응답을 즉시 받아야 하는 요청에 대해서는 적절하지 않을 수 있음에 유의해야 한다.

 


모니터링

 

모니터링을 통해, 현재 서버에 발생하는 트래픽에 따라 현재의 서버 구조가 이를 감당할 수 있는지 판단할 수 있다.

  • 에러 로그 : 시스템의 오류를 보다 쉽게 찾아낼 수 있다.
  • 메트릭 : 시스템의 현재 상태를 쉽게 파악할 수 있다.
    • 호스트 단위 메트릭 : CPU, 메모리, 디스크, I/O 등
    • 종합(Aggregated) 메트릭 : 데이터베이스 계층의 성능, 캐시 계층의 성능 등
    • 핵심 비즈니스 매트릭 : 일별 활성 사용자, 수익, 재방문 비율 등
  • 자동화 : 시스템이 크고 복잡해졌을 때, 생산성을 위해 빌드, 테스트, 배포 등의 자동화 도구를 활용할 수 있다.

 

 


 

 

참고 :

https://hudi.blog/system-design-interview-alex-xu-1/

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'개발' 카테고리의 다른 글

소프트웨어 아키텍처 패턴  (0) 2025.06.10
[ toss tech ] 서버 증설 없이 처리하는 대규모 트래픽  (0) 2025.06.02
equals & hashCode  (0) 2025.05.28
Call by 어쩌구  (0) 2025.05.23
파티셔닝과 샤딩  (0) 2025.05.19
'개발' 카테고리의 다른 글
  • 소프트웨어 아키텍처 패턴
  • [ toss tech ] 서버 증설 없이 처리하는 대규모 트래픽
  • equals & hashCode
  • Call by 어쩌구
sleepzzz214
sleepzzz214
아! 응애에요~!
  • sleepzzz214
    응애 개발자의 일지
    sleepzzz214
  • 전체
    오늘
    어제
    • ⭐ (55) N
      • 개발 (55) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    @Autowired
    스프링
    스프링 빈
    java
    싱글톤
    상태 패턴
    김영한 스프링 강의
    객체 지향 설계
    싱글톤 패턴
    프로토타입
    생성 패턴
    state
    스프링 핵심 원리 - 기본편
    Spring
    의존성 주입
    DB
    Solid
    모니터링
    행동 패턴
    객체 지향 프로그래밍
    상태
    의존 관계 주입
    제어의 역전
    DI
    스프링부트
    자바
    대규모 트래픽
    디자인 패턴
    데이터베이스
    구조 패턴
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
sleepzzz214
대규모 트래픽에 대처하는 방법
상단으로

티스토리툴바