- 초기 시스템이 몇백만 사용자가 될 때까지의 과정을 나타낸다.
단일 서버
모든 컴포넌트가 한대의 서버에서 실행되는 간단한 시스템 설계 웹 앱, 데이터베이스, 캐시 등이 전부 서버 한대에서 실행된다.
데이터베이스
관계형 데이터베이스
- 자료를
row, column
으로 표현
- sql을 사용하여 여러 테이블에 있는 데이터를
join
가능
- 트랜잭션의
ACID
를 지원
비-관계형 데이터베이스
키-값 저장소, 그래프 저장소
등으로 표현
- CouchDB, Neo4j, Amazon DynamoDB 등
- NoSQL은 스키마 없거나 유연한 스키마를 허용하며, 비구조화 데이터를 저장하는 데 적합
- 데이터(json, xml등)를 직렬화 하거나 역직렬화 할 수 있기만 하면 됨
- 아주 많은 양의 데이터를 저장할 필요가 있음
수직적 규모확장과 수평적 규모확장
수평적 규모 확장 (scale-out)
더 많은 서버를 추가
하여 성능을 개선하는 행위
수직적 규모 확장(scale-up)
단점
- 수직적 규모확장에
한계가 있다.
한대의 서버에 cpu나 메모리를 무한대로 증설할 방법은 없다.
장애에 대한 자동복구 방안이나 다중화 방안을 제시하지 않는다.
- 서버에
장애가 발생
하면 웹사이트/앱은 완전히 중단
된다.
해결 방법 : 이런 문제를 해결하는 데는 부하 분산기 또는 로드 밸런서를 도입하는 것이 최선이다.
로드밸런서
로드밸런서는 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.
Client
는 로드 밸런서의 공개 IP주소(Public IP)
로 접속한다. 따라서 웹 서버는 클라이언트의 접속을 직접 처리하지 않는다.
더 나은 보안을 위해, 서버 간 통신
에는 사설 IP(Private IP)
가 이용된다.
데이터베이스 다중화
데이터베이스 레플리케이션
- master(주)-slave(부)관계를 설정하고 데이터 원본은 주 서버에 사본은 부 서버에 저장하는 방식이다.
쓰기연산
은 마스터
에서만 지원한다. 슬레이브
는 마스터
로부터 사본을 전달받으며, 읽기 연산
만을 지원한다.
장점
- 더 나은 성능 : 마스터-슬레이브 모델에서
읽기 연산을 병렬로 처리
하여 성능 향상
- 안정성 :
데이터를 지역적으로 떨어진 여러 장소에 다중화
시켜 놓을 수 있다.
- 가용성 : 데이터를 복제함으로써 하나의 데이터베이스 서버에
장애가 발생하더라도 다른 서버의 데이터를 가져와 서비스
할 수 있다.
캐시
값 비싼 연산 결과
또는 자주 참조되는 데이터
를 메모리 안에 두고, 뒤 이은 요청이 보다 빨리 처리 될 수 있도록 하는 저장소
- 캐시 계층은 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다. 별도의 캐시 계층을 두면 성능이 개선될 뿐만 아니라
데이터베이스의 부하를 줄일 수 있고
, 캐시 계층의 규모를 독립적으로 확장
시키는것도 가능해진다.
고려할 점
- 캐시 데이터 선택 기준
- 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다.
- 캐시에 보관된 데이터 만료 시간
- 만료 기한이 없으면 데이터는 캐시에 계속 남게된다. 너무 짧으면 데이터베이스를 자주 읽게된다.
- 일관성 유지 방법
- 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리되지 않는 경우 이 일관성은 깨질 수 있다.
- 장애 대처 방법
- 데이터 방출(eviction) 정책
- 캐시가 꽉 차버리면 추가로 캐시에 데이터를 넣어야할 경우 기존 데이터를 내보내야한다.
- LRU, LFU 등
콘텐츠 전송 네트워크(CDN)
- 정적 콘텐츠를 전송하는데 쓰이는, 지리적으로 분산된 서버의 네트워크이다. 이미지, 비디오, CSS, JavaScript 파일등을 캐시할 수 있다.
고려할 점
- 비용
- CDN은 보통 제3 사업자(third-party provides)에 의해 운영되며, 개발자는 CDN으로 들어가고 나가는 데이터 전송 양에 따라 요금을 내게 된다. 자주 사용되지 않는 콘텐츠를 캐싱하는 것은 이득이 크지 않으므로, CDN에서 빼는 것을 고려하는 것이 좋다.
- 만료 시간
- 장애 대처 방법
- CDN 자체가 죽었을 경우 웹사이트/애플리케이션이 어떻게 동작해야 하는지 고려해야 한다. 일시적으로 CDN이 응답하지 않을 경우, 해당 문제를 감지하여 원본 서버로부터 직접 콘텐츠를 가져오도록 클라이언트를 구성하는 것이 필요할 수도 있다.
- 콘텐츠 무효화 방법
- 아직 만료되지 않은 콘텐츠라 하더라도 아래 방법 가운데 하나를 쓰면 CDN에서 제거할 수 있다. CDN 서비스 사업자가 제공하는 API를 이용하여 콘텐츠 무효화 콘텐츠의 다른 버전을 서비스하도록 오브젝트 버저닝(object versioning) 이용. 콘텐츠의 새로운 버전을 지정하기 위해서는 URL 마지막에 버전 번호를 인자로 주면 된다. (Ex. image.png?v=2)
무상태(stateless) 웹계층
- 상태 정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고, 필요할 때 가져오도록 구성된 웹 계층을 무상태 웹 계층이라고 부른다.
- 단순하고, 안정적이며, 규모 확장이 쉽다.
상태가 서버에 저장된다면?
- 서버가 많을 때 상태 정보를 각 서버에 저장한다면, 서버는 상태에 대한 정보를 얻기 위해 다른 서버를 확인해야한다.
- 로드밸런서가 고정세션 기능을 지원하지만, 로드밸런서에 부담을 주며 서버의 장애를 처리하기 복잡해진다.
데이터 센터
- 장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내되는데, 보통 이 절차를
지리적 라우팅
(geoDNS-routing 또는 geo-routing)이라고 부른다. 지리적 라우팅에서의 geoDNS는 사용자의 위치에 따라 도메인 이름을 어떤 IP 주소로 변환할지 결정할 수 있도록 해 주는 DNS 서비스다.
아래 그림에서, x% 사용자는 US-East 센터로, 그리고 (100 - x)%의 사용자는 US-West 센터로 안내된다고 하자.
이들 데이터 센터 중 하나에 심각한 장애가 발생하면 모든 트래픽은 장애가 없는 데이터 센터로 전송된다. 아래 그림은 데이터센터2(US-West)에 장애가 발생했을 때, 모든 트래픽이 데이터센터1(US-East)로 전송되는 상황이다.
이 사례와 같은 다중 데이터센터 아키텍처를 만들려면 몇 가지 기술적 난제를 해결해야 한다.
- 트래픽 우회: 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 한다. GeoDNS는 사용자에게서 가장 가까운 데이터센터로 트래픽을 보낼 수 있도록 해 준다.
- 데이터 동기화(synchronization): 데이터 센터마다 별도의 데이터베이스를 사용하고 있는 상황이라면, 장애가 자동으로 복구되어(failover) 트래픽이 다른 데이터베이스로 우회된다 해도, 해당 데이터센터에는 찾는 데이터가 없을 수 있다. 이런 상황을 막는 보편적 전략은 데이터를 여러 데이터센터에 걸쳐 다중화하는 것이다.
- 테스트와 배포(deployment): 여러 데이터 센터를 사용하도록 시스템이 구성된 상황이라면 웹 사이트 또는 애플리케이션을 여러 위치에서 테스트해보는 것이 중요하다. 자동화된 배포 도구는 모든 데이터 센터에 동일한 서비스가 설치되도록 하는 데 중요한 역할을 한다.
메세지 큐
- 메시지 큐는 메시지의 무손실(durability, 즉 메시지 큐에 일단 보관된 메시지는 소비자가 꺼낼 때까지 안전히 보관된다는 특성)을 보장하는, 비동기 통신을 지원하는 컴포넌트이다. 메시지의 버퍼 역할을 하며, 비동기적으로 전송한다.
- 서비스 또는 서버 간 결합이 느슨해진다.
- 생산자는 소비자 프로세스가 다운되어 있어도 메시지를 발행할 수 있고, 소비자는 생산자 서비스가 가용한 상태가 아니더라도 메시지를 수신할 수 있다.
메시지 큐 구조
- 생산자(or 발행자)라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발행한다.
- 큐에는 보통 소비자(or 구독자)라고 불리는 서비스 혹은 서버가 연결되어 있는데, 메시지를 받아 그에 맞는 동작을 수행한다.
로그, 메트릭 그리고 자동화
로그
- 에러 모니터링
- 로그를 단일 서비스로 모아주는 도구를 활용하면 더 편리하다.
메트릭
- 호스트 단위 메트릭 : CPU, 메모리, 디스크 I/O에 관한 메트릭
- 종합(aggregated) 메트릭: 데이터베이스 계층의 성능, 캐시 계층의 성능 같은것
- 핵심 비즈니스 매트릭: 일별 능동 사용자, 수익, 재방문 같은 것
자동화
- CI/CD 예시 : 빌드, 테스트, 배포 자동화
데이터베이스의 규모 확장
수직적 확장
단점
- 서버 스케일업과 마찬가지로 무한 증설 불가능
- 장애 대처 쉽지 않음 (SPOF)
- 비용이 많이 든다.
수평적 확장 (샤딩)
- 데이터베이스 샤딩은 데이터를 샤드라고 하는 더 작은 청크로 분할하고 여러 데이터베이스 서버에 저장
- 샤딩 키(파티션 키) : 데이터를 어떻게 분산할지 정하는 하나 이상의 컬럼
- 샤딩 키를 통해 데이터베이스에 질의를 보내 효율성 증가
고려할 점
- 데이터의 재 샤딩(resharding)
- 데이터가 많아져 하나의 샤드로는 감당하기 어려운 경우
- consistent hashing으로 해결
- 유명인사(celebrity) 문제
- 특정 샤드에 질의가 집중되어 서버에 과부하가 걸리는 문제
- 조인과 비정규화
- 여러 샤드에 걸친 데이터를 조인하기가 힘들다.
- 비정규화를 통해 하나의 테이블에서 질의가 수행될 수 있도록 한다.
최종 아키텍처