본문 바로가기
Spring/ETC

사용자 수에 따라 규모 확장하는 기법에 대해,

by YoonJong 2023. 4. 15.
728x90

신입 개발자로 입사한지 벌써 2달이 다되어갑니다.

현재 다니고 있는 회사의 서비스는 다른 대형 서비스(카카오톡 등)과 같이 아직 대규모적인 시스템은 아니지만,

성장성과 환경규제를 생각해보았을 때, 수백만이 이용할 수 있는 서비스라고 생각합니다.

따라서, 대규모 시스템을 설계하는데 있어 어떤 것을 고려해야할지 궁금하고 아키텍처 적으로 학습하고 싶어졌습니다.


"가상 면접 사례로 배우는 대규모 시스템 설계 기초" 라는 도서를 참고했습니다.

사용자 수에 따른 규모 확장성을 가장 먼저 소개하며, 어떤 기법을 고려하면 좋을지 먼저 목차를 보겠습니다.

 

- 웹 계층은 무상태 계층으로

- 모든 계층에 다중화 도입

- 가능한 한 많은 데이터를 캐시할 것

- 여러 데이터 센터를 지원할 것

- 정적 콘텐츠는 CDN을 통해 서비스할 것

- 데이터 계층은 샤딩(Scale out)을 통해 규모를 확장할 것

- 각 계층은 독립적으로 서비스를 분할할 것

- 시스템을 지속적으로 모니터링하고, 자동화 도구를 사용할 것

 

아래는 위의 기법을 적용한 아키텍처입니다.

100% 아래의 그림처럼 설계할 수는 없을 거라고 생각합니다.

효율을 올리고 각 서비스에 맞는 적합한 방법을 찾아야 합니다.

 


 

수백만 사용자를 지원하는 시스템을 설계하기 위해서 어떤 것을 준비하고 고려해야 하는지 알아보겠습니다.

 

처음부터 대규모 설계를 고려하는 것도 좋지만, 시작에 있어서는 가장 간단하게 작성 후 분석을 통해 확장하는 것이 좋습니다.

 

가장 간단하게 단일 서버를 이용하면 아래와 같이 실행됩니다.

사용자는 api.mysite.com 으로 접속하면 DNS 서버에서 IP 주소를 보내주고, 해당 IP 주소로 요청이 전달됩니다.

웹 서버는 데이터베이스에서 필요한 CRUD 작업을 진행하고 데이터를 반환받아 사용자에게 응답을 내려줍니다.

 

여기서 데이터베이스는 관계형 / 비관계형으로 나뉘게 되는데, 어느 상황에 어떤 형태의 데이터베이스를 선택해야 하는지는 따로 검색해보는 것을 추천합니다.

 

서버의 규모를 확장함에 있어서 수직적 규모 확장과 수평적 규모 확장(샤딩)을 선택할 수 있습니다.

수직적 규모 확장(Scale up) 은 사양을 더 좋게 업그레이드 하는 것을 의미합니다.

수평적 규모 확장(Scale out)은 서버의 개수를 늘리는 것을 의미합니다.

 

서버에 유입되는 트래픽이 적을 때는 Scale up을 선택하는 것이 효율적이지만, 해당 방법은 사양의 한계가 있으며,

해당 서버가 장애가 발생하면 전체의 서비스가 중단되기 때문에 정확한 판단이 필요합니다.

대규모 애플리케이션에 있어서는 Scale Out 을 통해 서버의 개수를 늘리고 로드밸런서를 도입하는 것이 최선입니다.

 

로드밸런서는 부하 분산 집합으로 생성되어 있는 웹 서버에게 트래픽을 분산시켜주는 역할을 합니다.

사용자는 서버로 직접 접속하는 것이 아닌, 로드밸러서의 public IP 에 접속합니다.

로드밸런서가 각 서버의 private IP 를 이용하여 서버에 접근합니다.

트래픽의 분산 뿐만 아니라, 서버1 이 다운될 시, 서버2 를 통해 정상적으로 서비스를 운영할 수 있습니다.

 

서버에 대해 알아보았는데, 데이터베이스는 어떤 방식이 있을까요?

 

데이터베이스 관리 시스템은 다중화를 지원하며, 보통은 주서버에서 데이터 원본을 관리하고, 부서버에서 데이터 사본을 관리합니다.

쓰기 연산은 마스터에서만 지원하고, 부서버에서는 읽기(SELECT)를 지원하는 것이 일반적입니다.

데이터베이스를 다중화하면 성능측면 뿐만 아니라, 장애 대처에 있어 안정성과 가용성에 대해서도 장점이 있습니다.

 

응답시간을 개선시켜 줄 수 있는 캐시와 CDN에 대해 알아보겠습니다.

 

애플리케이션의 성능은 데이터베이스에서 얼마나 처리를 빠르게 처리해 줄수 있는지가 중요합니다.

캐시는 비용이 큰 연산결과와 자주 참조되는 데이터를 메모리 안에 저장하고, 동일한 요청이 들어올 경우 빨리 처리해 줄수 있는 저장소입니다.

캐시의 속도가 빠를 수록 비용이 비싸기 때문에 조절해서 사용해야 합니다.

캐시를 고려해야할 점에 대해 알아보겠습니다.

1. 데이터 갱신은 자주 일어나지 않지만, 참조는 자주 발생할 때.

2. 캐시는 휘발성 데이터로 영속적으로 보관할 데이터는 부적합.

3. 만료시간이 너무 짧으면 데이터베이스를 자주 읽을 것이고, 너무 길면 데이터원본 변경 시 정합성이 맞지 않음.

4. 캐시 메모리의 크기를 얼마나 잡을지.

5. 메모리의 크기가 꽉 차면 어떤 캐시 데이터 방출 정책을 사용할지. ex) LRU ( 마지막으로 사용된 데이터 내보냄 )

 

콘텐츠 전송 네트워크(Content Delivery Network) 에 대해 알아보겠습니다.

CDN 은 정적 콘텐츠를 전송하는데 쓰이는, 이미지 비디오 등을 캐시할 수 있습니다.

사용자가 웹사이트를 방문하면 가장 가까운 CDN 서버에 정적 컨테츠를 전달하게 됩니다.

고려해야할 사항은 캐시와 비슷합니다.

CDN 사용시 데이터 전송량에 따라 비용이 발생하기 때문에, 비용관련된 문제가 있을 수 있습니다.

컨텐츠의 정합성을 위해 만료일자를 고려해야합니다.

 

 

웹 계층을 수평적으로 확장하기 위해서는 무상태(Stateless) 로 설계해야 합니다.

 

상태 정보에 의존적(State)인 아키텍처는 상태를 유지하여 요청들 사이에 정보가 공유됩니다.

아래 사진과 같이 사용자 A를 인증하기 위해서는 서버1로 전송이 되어야 합니다.

클라이언트의 요청은 서버2, 서버3으로 갈수 있는데 상태유지가 될 경우 서버 1을 제외한 다른 서버에서도 사용자A 의 정보를 모두 저장하고 있어야 하기 때문에 서버에 부담이 갑니다.

 

로드밸런서의 고정 세션을 통해 사용자A의 요청은 서버1로만 갈 수 있도록 할 수 있지만, 로드밸런서의 부담을 줄 수 있기때문에 지양한다고 합니다.

 

이를 해결해 줄 수 있는 Stateless 방법을 살펴보겠습니다.

무상태 아키텍쳐이기 때문에, 사용자의 요청은 어느 서버로 가도 상관없습니다.

단순하고 안정적이며 규모 확장이 쉽습니다.

 

 

추가적으로 , 데이터 센터를 이용해서 더욱 안정적인 웹 서비스를 운영할 수 있습니다.

웹 데이터 센터를 2개라고 가정했을 시, 하나의 센터에 장애가 발생하면 나머지 센터로 데이터가 전송되게 함으로써 장애에 대응할 수 있습니다.

 

 

대규모 분산 시스템에서 사용하고 있는 핵심적 전략기법인 메시지 큐에 대해서 알아보겠습니다.

메시지 큐는 메시지의 무손실을 보장하며, 비동기 통신을 지원합니다.

생산자(producer) or 발행자(publisher) 라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발행(publish)합니다.

큐에는 소비자(consumer) or 구독자(subscriber) 라 불리는 서비스 혹은 서버가 연결되어 있습니다.

메시지 큐를 사용하게 되면 프로세스가 다운되어도 메시지를 발행할 수 있습니다.

카카오톡에서 사진을 보내면서 채팅을 칠 수 있는 것을 예시로 들수 있습니다.

728x90

댓글