단일 서버

모든 컴포넌트가 단 한 대의 서버에서 실행되는 시스템. 웹앱, 데이터베이스, 캐시 등이 전부 서버 한 대에서 실행되는 상태.
1) 사용자는 도메인 이름(api.mysite.com)을 이용해서 웹 사이트에 접속
2) 접속을 위해서는 도메인 이름 서비스(DNS)에서 질의하여 IP 주소 변환
3) 15.125.23.214 웹 서버의 주소를 반환 받은 후 해당 IP 주소로 HTTP 요청이 전달
4) 요청 받은 웹 서버는 HTML 페이지나 JSON 형태의 응답을 반환

데이터베이스

웹/모바일 트래픽 처리 서버(웹 계층)와 데이터베이스 서버(데이터 계층)를 분리하면 각각 독립적으로 확장해 나갈 수 있다.

데이터베이스 종류

  • 관계형 데이터베이스(RDBMS): 관계형 데이터베이스 관리 시스템, 자료를 열과 컬럼으로 표현한다. SQL을 사용하면 여러 테이블에 있는 데이터를 관계에 따라 조인(join)하여 합칠 수 있다.
  • 비 관계형 데이터베이스(NoSQL): 일반적으로 조인 연산은 지원하지 않는다.
    • 키-값 저장소(key-value store)
    • 그래프 조장소(graph store)
    • 칼럼 저장소(column store)
    • 문서 저장소(document store)

비관계형 데이터베이스가 바람직한 선택일 수 있는 경우

  • 아주 낮은 응답 지연시간(latency)
  • 비정형 데이터를 다룰 때
  • 데이터(JSON, YAML, XML)를 직렬화하거나(serialize) 역직렬화(deserialize)할 수 있기만 하면 됨
  • 아주 많은 양의 데이터를 저장할 필요가 있을 때

수직적 규모 확장 vs 수평적 규모 확장

  • 수직적 규모 확장(scale up): 서버에 고사양 자원(CPU,RAM)을 추가하는 행위
  • 수평적 규모 확장(scale out): 더 많은 서버를 추가해서 성능을 개선하는 행위

서버로 유입되는 트래픽 양이 적을 때는 수직적 확장이 좋은 선택이다. 하지만 한 대의 서버에 CPU나 메모리를 무한대로 증설할 수 있는 방법이 없고, 장애에 대한 자동복구나 다중화 방안을 제시하지 않는다. 서버에 장애가 발생하면 웹사이트/앱은 완전히 중단된다.
수직적 확장의 이런 단점 때문에 대규모 애플리케이션을 지원할 때는 수평적 규모 확장법이 적절하다.

로드밸런서

로드밸런서는 부하 분산 집합(load balancing set)에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.

데이터베이스 다중화

서버 사이에 주(master)-부(salve) 관계를 설정하고 데이터 원본은 주 서버에, 사본은 부 서버에 저장하는 방식이다.
쓰기 연산은 마스터에서만 지원한다. 부 데이터베이스는 주 데이터베이스로부터 사본을 전달받으며 읽기 연산만을 지원한다. 데이터베이스를 변경하는 명령어들(insert, delete, update)은 주 데이터베이스로만 전달되어야 한다. 대부분의 애플리케이션은 읽기 연산의 비중이 쓰기 연산보다 훨씬 높다. 그래서 부 데이터베이스가 주 데이터베이스의 수보다 많다.

데이터베이스 다중화로 인한 이득은 다음과 같다.

  • 더 나은 성능: 병렬로 처리될 수 있는 질의(query)의 수가 늘어나므로 성능이 좋아진다.
  • 안정성(reliability): 서버 일부가 파괴되어도 데이터는 보존될 것이다. 데이터를 지역적으로 떨어진 여러 장소에 다중화시켜 두었기 때문이다.
  • 가용성(availability): 데이터를 여러 지역에 복제해 둠으로써 하나의 데이터베이스가 장애가 생겨도 다른 서버에 있는 데이터를 가져와서 계속 서비스할 수 있게 된다.

캐시

캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고 뒤이은 요청이 빨리 처리될 수 있도록 하는 저장소이다. 애플리케이션의 성능은 데이터베이스를 얼마나 자주 호출하느냐에 크게 좌우되는데, 캐시는 그런 문제를 완화할 수 있다.

캐시 계층

캐시 계층(cache tier)은 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다. 성능 개선과 데이터베이스의 부하를 줄일 수 있고, 캐시 계층의 규모를 독립적으로 확장시키는 것도 가능해진다.

캐시 서버를 이용하는 방법은 대부분의 캐시 서버들이 API를 제공하기 때문에 이를 사용하면 된다.

SECONDS=1
cache.set('myKey', 'hi there',3600*SECONDS)
cache.get('myKey')

캐시 사용 유의점

  • 데이터 갱신은 자주 일어나지 않지만 참조는 빈번하게 일어난다면 사용을 고려
  • 캐시 서버가 재시작되면 데이터는 사라지기 때문에 중요한 데이터는 주 데이터베이스에 두는 것이 좋다.
  • 캐시 서버를 한 대만 두면 단일 장애 지점(Single Point of Failure, SPOF)이 되어버릴 가능성이 있다. 어떤 특정 지점에서의 장애가 전체 시스템의 동작을 중단시켜버릴 수 있는 경우를 의미하는데, 이를 방지하기 위해 여러 지역에 캐시 서버를 분산시켜야 한다.

콘텐츠 전송 네트워크(CDN)

CDN은 정적 콘텐츠를 전송하는데 쓰이는 분산된 서버의 네트워크이다. 이미지, 비디오, CSS, JavaScript 파일 등을 캐시할 수 있다.

CDN 사용 유의점

  • CDN은 보통 제3 사업자(third-party providers)에 의해 운영되며, CDN으로 들어가고 나가는 데이터 전송 양에 따라 요금을 내게 된다.

  • 콘텐츠 무효화(invalidation) 방법: 아직 만료되지 않은 콘텐츠라 하더라도 아래 방법을 사용하면 CDN에서 제거할 수 있다.

    	- CDN 서비스 사업자가 제공하는 API를 사용해서 콘텐츠 무효화
    • 콘텐츠의 다른 버전을 서비스하도록 오브젝트 버저닝(object versioning) 이용

CDN과 캐시가 추가된 설계


1. 정적 콘텐츠(JS, CSS, 이미지 등)는 웹 서버를 통해 서비스하지 않고 CDN을 통해 제공한다.
2. 캐시가 데이터베이스 부하를 줄여준다.

무상태(stateless) 웹 계층

웹 계층을 수평적으로 확장하기 위해 상태 정보(사용자 세션 데이터 등)를 웹 계층에서 제거해야 한다. 상태 정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고 필요할 때 가져오도록 한다. 이렇게 구성된 웹 계층을 무상태 웹 계층이라 부른다.

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

무상태 아키텍쳐


출처: 가상 면접 사례로 배우는 대규모 시스템 설계 기초(알렉스 쉬 지음)
profile
공부기록

0개의 댓글