설계 방법론: 사용자 수에 따른 규모 확장성(4)

최건우·2023년 7월 16일
0

이제, 웹 계층을 수평적으로 확장하는 방법을 생각해 보자.

무상태(stateless) 웹 계층

무상태 웹 계층이란 상태 정보(사용자 세션 데이터 등)를 웹 계층에서 제거한 것을 의미한다. 상태 정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고, 필요할 때 가져오도록 하는 형태이다.

상태 정보 의존적인 아키텍처

서버가 상태 정보 의존적이라는 뜻은 클라이언트 정보(=상태)를 유지하여 요청 사이에 공유되도록 한다는 뜻이다. 상태 의존적인 아키텍처의 문제점은 클라이언트의 요청이 항상 같은 서버로 전송되어야 한다는 것이다. 만약 서버가 1부터 10까지 여러 대가 있다고 가정해 보자. 유저 A에 관한 데이터가 서버 3에 보관되어있다면, 유저 A로부터의 요청은 항상 서버 3으로만 전송되어야 한다. 그렇지 않으면 인증에 실패할 것이다.

무상태 아키텍처

무상태 아키텍처는 아래와 같은 구조로 되어있다.

이러한 구조에서 사용자의 HTTP 요청은 어떤 웹 서버로도 전달될 수 있다. 웹 서버는상태 정보가 필요하다면 공유 저장소로부터 데이터를 가져오면 되므로, 상태 정보는 웹 서버로부터 물리적으로 분리되어 있다. 따라서 구조가 단순하고, 안정적이며, 규모 확장이 쉽다.

무상태 웹 계층을 갖는 전체 시스템은 다음과 같다.

웹 계층에서 세션 데이터를 분리하고, 지속성 데이터 보관소에 저장하도록 만들었다. 이 공유 저장소는 NoSQL, RDBMS, 캐시 시스템 등 무엇이든 될 수 있다. 다만 NoSQL은 규모 확장이 간편하다는 장점이 있어 고려해볼 만한 선택지이다. 또한 상태 정보가 웹 서버에서 제거되었으므로, 트래픽 양에 따라 웹 서버를 자동으로 추하거나 삭제하기만 하면 자동으로 규모를 확장할 수 있게 된다(autoscaling).

데이터 센터(data center)

전 세계 사용자들이 이용하는 서비스에서 가용성을 높이고 어디서든 쾌적하게 사용할 수 있도록 하기 위해서는 데이터 센터가 필요하다.

아래와 같이 두 개의 데이터 센터를 이용하는 상황을 가정해 보자.

지리적 라우팅(geo-routing 또는 geoDNS-routing)이란 장애가 없는 상황에서 사용자를 가장 가까운 데이터 센터로 안내해 주는 절차를 의미한다. geoDNS는 사용자의 위치에 따라 도메인 이름을 어떤 IP 주소로 변환할지 결정할 수 있도록 해 주는 서비스다. 만약 하나의 데이터 센터에 장애가 발생하면, 모든 트래픽은 장애가 없는 데이터 센터로 전송된다.

다중 데이터 센터 아키텍처를 만들기 위해서는 몇 가지 기술적 난제를 해결해야 한다.

  1. 트래픽 우회
    GeoDNS로 사용자에게서 가장 가까운 데이터 센터로 트래픽을 보낼 수 있도록 하는 것과 같이, 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 한다.
  2. 데이터 동기화
    데이터 센터마다 별도의 데이터베이스를 사용하고 있다면, 데이터 센터마다 데이터 현황이 다를 수 있다. 이럴 경우 트래픽이 다른 데이터베이스로 우회되더라도, 해당 데이터 센터에는 찾는 데이터가 없을 수도 있다. 이런 상황을 막는 보편적 전략은 데이터를 여러 데이터 센터에 걸쳐 다중화하는 것이다(ex. 넷플릭스).
  3. 테스트와 배포
    야러 데이터 센터를 사용하도록 웹 사이트 또는 애플리케이션을 여러 위치에서 테스트해보는 것이 중요하다.

메시지 큐(message queue)

메시지 큐는 많은 분산 시스템에서 사용하고 있는 방식이다. 시스템을 더 큰 규모로 확장하기 위해서는, 시스템의 컴포넌트를 분리하여 각기 독립적으로 확장될 수 있도록 해야 하는데 이때 메시지 큐가 사용된다.

메시지 큐란 무손실(durability)을 보장하는, 비동기 통신을 지원하는 컴포넌트다. 한 번 메시지 큐에 보관된 메시지는 소비자가 꺼낼 때까지 안전히 보관되는 특성을 갖는다. 기본 아키텍처는 다음과 같다.

  • 생산자 혹은 발행자(producer/publisher)라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발행(publish)한다.
  • 큐에 연결된 소비자 혹은 구독자(consumer/subscriber)라 불리는 서비스 혹은 서버는 메시지를 받아 그에 맞는 동작을 수행한다.

서비스 또는 서버 간 결합의 느슨해져서, 규모 확장성이 보장되어야 하는 안정적인 애플리케이션을 구성하기 좋다. 생산자는 소비자 프로세스가 다운되어 있어도 메시지를 발행할 수 있고, 소비자는 생산자 서비스가 가용한 상태가 아니더라도 메시지를 수신할 수 있다. 또한, 생산자와 소비자 서비스의 규모는 각기 독립적으로 확장될 수 있다.

요청을 수행하는 시간이 오래 걸리는 프로세스를 비동기적으로 처리하고 싶을 때 메시지 큐를 이용하면 편리하다. 사진을 업로드하면 cropping, sharpening, blurring 등의 시간이 오래 걸리는 후처리를 해 주는 보정 애플리케이션 예를 들어 보자. 웹 서버(생산자)가 사진 보정 작업(Job)을 메시키 쥬에 넣으면, 사진 보정 작업(소비자, worker) 프로세스들은 이 작업을 메시지 큐에서 꺼내어 비동기적으로 완료한다.

다만, 큐의 크기가 커지면 더 많은 작업 프로세스(=소비자)를 추가해야 처리 시간을 줄일 수 있다.

로그, 메트릭 그리고 자동화

로그

에러 로그를 모니터링하는 것은 시스템의 오류와 문제들을 쉽게 찾아낼 수 있도록 하므로 중요하다. 서버 단위로 모니터링 할 수도 있지만, 로그를 단일 서비스로 모아주는 도구를 활용하면 더 편리하게 검색할 수 있다.

메트릭(metric)

메트릭은 비즈니스적으로 유용한 정보를 얻을 수도 있고, 시스템의 현재 상태를 손쉽게 파악할 수도 있다. 메트릭 중 유용한 것에는 다음과 같은 것들이 있다.

  • 호스트 단위 메트릭
    • CPU, 메모리, disk I/O 등의 지표
  • 종합(aggregated) 메트릭
    • 데이터베이스 계층의 성능이나 캐시 계층의 성능 등
  • 핵심 비즈니스 메트릭
    • DAU, 리텐션(재방문), 수익(revenue) 등

자동화(automation)

크고 복잡한 시스템에서 생산성을 높이기 위해 자동화 도구를 활용해야 한다. CI/CD는 코드 변경사항의 검사, 빌드, 테스트, 배포 등의 절차를 자동화할 수 있어 생산성을 향상시킬 수 있다.

메시지 큐, 로그, 메트릭, 자동화 등을 반영한 시스템 설계의 예시는 아래와 같다.





출처: 가상 면접 사례로 배우는 대규모 시스템 설계 기초

profile
부족한 경험을 채우기 위한 나만의 기록 공간

2개의 댓글

comment-user-thumbnail
2023년 7월 17일

저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!

1개의 답글