2020년 2월 12일 수요일

규모에 따라 서비스 확장하기 (Application Scaling)

웹과 모바일 앱 애플리케이션은 일반적으로 3개의 컴포넌트로 구성된다.

  • 데이터베이스
  • API
  • 클라이언트

데이터베이스는 데이터를 보관하고, API는 요청에 따른 데이터를 서빙한다. 그리고 클라이언트는 데이터를 렌더링해 사용자에게 표시한다. 클라이언트와 API를 구분하는 이유는, 클라이언트와 API를 완전히 별개의 개체로 생각하고 미리 구분해두면 애플리케이션 확장에 대한 추론이 훨씬 간단해지기 때문이다.


다음은 서비스를 시작한 뒤 서서히 사용자(트래픽)가 증가하게 될 때 애플리케이션을 어떻게 구성(대응)해야 하느냐에 대한 가이드다. 원문은 아래 링크에 있다. (아래의 내용은 원문에 대한 번역이 아니기 때문에 영어에 익숙하다면 원문의 내용을 참고하는 것이 좋다.)
https://alexpareto.com/scalability/systems/2020/02/03/scaling-100k.html


1~10 Users : 하나의 서버

아주 적은 사용자(1~10명)를 대상으로 할 땐 위의 세가지 컴포넌트를 하나의 서버에서 실행되게 하는 것이 좋을 것이다. 한 명의 엔지니어가 데이터베이스, API, 클라이언트를 모두 통제할 수 있기 때문이다.


10~100 Users : 데이터베이스 분리

사용자가 10~100명 수준이 된다면 가장 먼저 고려할 것은 데이터베이스를 물리적으로 분리하는 것이다. 클라우드 환경이라면 아마존 RDS 같은 것이 될 수 있는데, 비용이 조금 비싸지지만 멀티-리젼 중복, 읽기 전용 복제본 생성, 자동 백업 등 다양한 기능을 쉽게 추가할 수 있다.


100~1000 Users : 클라이언트 분리

사용자가 100명을 넘어서면서 트래픽이 안정적으로 나와주면 클라이언트 컴포넌트 까지도 분리를 고려해야 한다. 앞서 적힌 내용처럼 최초 구현 단계에서부터 클라이언트와 API 컴포넌트를 명확히 구분지어 놓으면 확장이 쉬워진다. (API 입장에선 클라이언트가 웹이든 데스크탑이든 그저 같은 API를 사용하는 클라이언트일 뿐이다.)


1000+ Users : Load balancer

하나의 API 인스턴스가 모든 트래픽을 감당하기 어려워지게 되므로 더 많은 컴퓨팅 파워가 필요하게 된다.

로드 밸런서가 투입된다. API 앞에 로드 밸런서를 배치하고 트래픽을 분산시키는 방식이다. 이를 통해 수평적 확장이 가능하게 된다. 동일한 코드를 실행하는 서버를 추가할수록 처리할 수 있는 요청량은 늘어나게 된다. 로드 밸런서는 트래픽이 가장 적은 인스턴스로 요청을 라우팅한다. (물론 처음 연결맺은 API 인스턴스와 계속 통신하게 할수도 있다.)


10,000+ Users : CDN

정적 컨텐츠를 API 서버로부터 구분한다. 이 작업은 초기에 해두는 것이 좋긴 하다. 그리고 CDN 도입을 고려해야 한다. CDN은 전 세계의 다른 데이터 센터에 정적인 데이터를 자동으로 캐시한다.


100,000+ Users: 데이터베이스에 대한 확장

데이터베이스에 대한 스케일링 작업은 매우 어려운 편이다. API 서버의 경우 무상태(stateless)로 구성할 수 있어 확장이 간편하지만 데이터베이스의 경우 '상태'를 갖기 때문이다.

데이터베이스의 부하를 낮추기 위한 가장 간편하고 효과적인 선택은 데이터 보관에 대한 캐시 레이어를 마련하는 것이다. Redis 또는 Memcached와 같은 키-밸류 기반의 메모리 저장 솔루션이 이를 지원한다. 특히 Redis의 경우 자체로 클러스터링을 지원하기 때문에 확장으로부터 안전하다. 여기서 더 할 수 있는 일은 읽기에 대한 복제본(Read replica)를 추가하거나 파티셔닝, 샤딩 등의 기법을 사용하는 것이 도움이 된다.


+ 모니터링 도구
New Relic 또는 Datadog과 같은 서비스를 이용해 시스템을 모니터링할 수 있다. 이를 통해 요청이 느리고 개선이 필요한 부분을 파악할 수 있을 것이다.

댓글 없음:

댓글 쓰기