가상 면접 사례로 배우는 대규모 시스템 설계 기초 Study [1장] 사용자 수에 따른 규모 확장성
Contents
Note
팀 내에서 진행하는 Study 정리 입니다.
함께 논의하고 싶은 주제
- 우리 서비스의 검색기능은 아직 없지만 인스타그램처럼 태그, 유저, 장소 등 통합 검색 기능이 추가되면 어떤 구조를 가져가면 좋을까요?
단일서버
모든 컴포넌트가 단 한대의 서버에서 실행되는 간단한 시스템
- 도메인 이름을 이용하여 웹사이트에 접속. 도메인 이름은 도메인 이름 서비스(Domain Name Service, DNS)에 질의하여 IP 주소 반환
- DNS 질의 결과로 IP 반환
- IP 주소로 HTTP
HyperText Transfer Protocol
요청이 전달 - 요청을 받은 웹 서버는 HTML 페이지 JSON 형태의 응답을 반환
데이터베이스
관계형 데이터베이스(Relational Data-base Management System, RDBMS)가 개발자들에게는 익숙하고 오랜기간 동안 잘 사용되어진 시스템이지만 구축하려는 시스템에 따라 꼭 최선의 시스템은 아닐 수 있다. 아래의 경우 비-관계형 데이터가 바람직한 선택이 될 수 있다.
비-관계형 데이터베이스가 적합한 서비스
- 아주 낮은 응답 지연시간
latency
이 요구 - 다루는 데이터가 비정형
unstructured
이라 관계형 데이터가 아님 - 데이터(JSON, YAML, XMAL 등)를 직렬화하거나
serialize
역직렬화deserialize
할 수 있다 - 아주 많은 양의 데이터를 저장할 필요가 있다.
수직적 규모 확장과 수평적 규모 확장
- 수직적 규모 확장(
vertical scaling
) :scale up
. 프로세서는 서버에 고사양 자원을 추가하는 행위 - 수평적 규모 확장(
scale out
) :scale out
. 더 많은 서버를 추가하여 성능을 개선하는 행위
수직적 규모 확장의 단점
아래와 같은 단점때문에 대규모 애플리케이션을 지원하는 데는 수평적 규모 확장법이 적절하다.
- 확장의 한계가 있다. (CPU, 메모리를 무한대로 증설할 방법은 없다.)
- 장애의 자동복구(
failover
) 방안이나 다중화re-dundancy
방안을 제시하지 않음
로드 밸런서
로드 밸런서는 부하 분산 집합load balancing set
에 속한 웹 서버들에게 트래픽 부하를 고르게 분산함으로서 장애 자동복구와 웹 계층의 가용성을 향상시킬 수 있다.
- 서버 1이 다운되면 모든 트래픽은 서버 2로 전송된다. 따라서 웹 사이트 전체가 다운되는 일이 방지된다.
데이터베이스 다중화
- 데이터베이스 서버를 주
master
-부slave
관계를 설정하고 데이터 원본은 주 서버에, 사본은 부 서버에 저장하는 방식 - 쓰기 연산은 마스터에서만 지원하며 부 데이터베이스는 주 데이터베이스로부터 사본만 전달받고 읽기 연산만을 지원한다.
데이터베이스를 다중화 했을 때 장점
- 더 나은 성능 : 읽기 연산은 부 데이터베이스 서버로 분산됨으로서, 병렬로 처리될 수 있는 질의
query
수를 늘릴 수 있다. - 안정성
reliability
: 데이터를 지역적으로 분산시킴으로써 다중화 시켜 데이터베이스가 일부 파괴되더라도 데이터를 보존할 수 있다. - 가용성
availability
: 데이터를 여러지역에 복제함으로써, 하나의 데이터베이스 서버에 장애가 발생해도 다른 서버의 데이터를 가져와 계속 서비스할 수 있다.
데이터베이스 다중화 시 발생할 수 있는 상황
- 부 서버가 한 대 뿐인데 다운된 경우 : 읽기 연산은 한시적으로 주 데이터베이스로 전달되고 즉시 새로운 부 데이터베이스가 장애 서버를 대체한다.
- 부 서버가 여러대 : 읽기 연산은 나머지 부 데이터베이스 서버로 분산하여 장애 서버를 대체한다.
- 부 서버가 한대이며 주 데이터베이스가 다운되었을 때 : 부 데이터베이스가 새로운 주 서버가 되고 모든 연산을 처리한다. 그리고 새로운 부 데이터베이스가 추가된다.
- 부 서버에 보관된 데이터가 최신 상태가 아닐 수 있다.
- 복구 스크립트
recovery script
를 돌려서 데이터를 동기화 해야 한다. - 다중 마스터, 원형 다중화
circular replication
방식을 도입하여 대처
- 복구 스크립트
로드밸런서와 데이터베이스 다중화를 고려한 설계안
- 사용자는 DNS로부터 로드밸런서의 공개 IP 주소를 받는다.
- 사용자는 해당 IP 주소를 사용해 로드밸런서에 접속
- HTTP 요청은 서버 1이나 서버 2로 전달 된다.
- 웹 서버는 사용자의 데이터를 부 데이터베이스 서버에서 읽는다.
- 웹 서버의 데이터 변경 연산은 주 데이터베이스로 전다로딘다. (데이터 추가, 삭제, 갱신 연산 등)
캐시
- 캐시는 값 비싼 연산 결과, 자주 참조되는 데이터를 메모리에 두고 빨리 처리 될 수 있도록 하는 저장소
- 애플리케이션 성능은 얼마나 자주 데이터베이스를 호출하느냐에따라 크게 좌우되는데 캐시는 그런 문제를 완화할 수 있다.
캐시 계층
- 데이터베이스보다 빠르다. 별도의 캐시 계층을 통해 성능을 개선 시킬 수 있다.
읽기 주도형 캐시 전략 read-through caching strategy
- 웹서버는 캐시에 응답이 저장되어있는지 요청
- 데이터가 캐시에 없으면 데이터베이스에서 해당 데이터 읽어 캐시에 씀
- 데이터가 캐시에 있으면 캐시 데이터를 반환
캐시 사용시 유의할 점
- 캐시를 쓰는 상황 : 데이터 갱신은 자주 일어나지 않지만 참조는 빈번한 경우
- 캐시에 두는 데이터 : 영속적으로 보관할 데이터는 안됨
- 캐시 만료
expire
정책을 마련해야 한다. 너무 짧은 경우 데이터베이스 조회가 빈번하고 길 경우 원본가 차이가 날 수 있다. - 일관성
consistency
유지 방법 - Scaling Memcache at Facebook - 장애 대처 방법 : SOF를 피해 여러 캐시 서버를 분산 관리
- 캐시 메모리 크기 : 너무 작으면 액세스 패턴에 따라 데이터가 방출
eviction
되어 캐시 성능이 떨어짐 - 데이터 방출 정책
eviction
- 사용되지 않는 캐시 데이터를 삭제함으로써 캐시 메모리의 공간을 확보하는 것
- LRU(Least Recently Used), LFU(Less Frequently Used) 등 여러 전략이 존재한다.
CDN
요청 경로request path
, 질의 문자열query string
, 쿠키cookie
, 요청헤더request header
등의 정보에 기반 HTML 페이지를 캐시
CDN 사용지 고려해야 할 사항
- 비용 : CDN 써드파티 사업자에 의해 운영, 데이터 전송양에 따라 요금 부과
- 적절한 만료 시한 설정
- CDN 장애에 대한 대처 방안
- 콘텐츠 무효화
invalidation
방법- CDN 서비스 사업자가 제공하는 API 사용
- 오브젝트 버저닝(object versioning) 사용 : URL 마지막에 버전 번호 인자로 호출
무상태stateless
웹 계층
- 상태 정보(사용자 세션 데이터 등)를 웹 계층에 제거하여 서비스 하는 것
- 바람직한 전략 : 지속적 저장소에 보관하고 필요할 때 가져도록 한다.
- 고전적인 웹 서버 형태
- 세션 유지를 위해 같은 클라이언트로부터의 요청은 항상 같은 서버로 전송되어야 함
- 로드밸런서가 이를 지원하기 위해 고정 세션
stick session
을 제공하나 많은 부담을 준다.
무상태 아키텍처
- HTTP 요청은 어떤 웹 서버로도 전달 될 수 있다.
- 웹 서버의 상태 정보가 필요할 경우 공유 저장소
shared storage
로 부터 데이터를 가져온다. - 웹 서버와 물리적으로 분리되어있고 단순하고 안정적이며 규모확장이 쉽다.
데이터 센터
- 지리적 라우팅(
geoDNS-routing, geo-routing
) : 사용자가 지리적으로 가까이 위치한 데이터 센터로 연결
다중 데이터 센터 아기텍처를 만들기 위한 기술적 난제
- 트래픽 우회 : 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법
- 데이터 동기화
- 테스트와 배포
메세지 큐
- 메세지의 무손실
durability
보장하고 비동기 통신을 지원하는 컴포넌트 - 서비스 또는 서버간 결합도가 낮아지고 규모 확장성이 보장되어야하는 안정적 애플리케이션에 적합
메세지 큐의 기본 구조
- 생산자/발행자에 서비스에 의해 메세지를 생성하고 큐에 발행
pulbish
한다. - 소비자/구독자 서비스는 큐에 연결되어 있어 발행된 큐의 메세지를 받아 동작을 수행한다.
로그, 메트릭 그리고 자동화
로그
- 시스템의 오류와 문제들을 에러 로그를 통해 쉽게 찾을 수 있다.
메트릭
- 메트릭을 잘 수집하면 사업 현황에 관한 유용한 정보를 얻고 시스템 현재 상태를 손쉽게 파악 가능하다.
- 호스트 단위 메트릭 : CPU 메모리, 디스크 I/O에 관한 메트릭이 여기에 해당
- 종합
aggregated
메트릭 : 데이터베이스 계층의 성능, 캐시 계층의 성능 등 - 핵심 비즈니스 메트릭 : DAU, 수익
revenue
, 재방문retention
같은 것이 여기에 해당
자동화
- 지속적 통합을 도와주는 도구를 활용하여 개발자가 만든 코드를 검증하여 문제를 쉽게 감지
- 빌드, 테스트, 배포 등의 절차를 자동화 -> 개발 생산성 향상
데이터베이스 규모 확장
수직적 확장
- 고성능의 자원(CPU, RAM, 디스크 등)을 증설하는 방법
- SPOF(Single Point of Failure)로 인한 위험성이 크다
- 비용이 많이 든다.
수평적 확장
샤딩은 샤드라고 부르는 작은 단위로 데이터를 분할하는 기술
샤딩 전략 구현시 고려할 점
- 샤딩 키(파티션 키) 정의 방법 : 데이터를 고르게 분포할 수 있는게 가장 중요
- 데이터의 재 샤딩
resharding
- 데이터가 너무 많아져서 하나의 샤드로 감당이 어려울 때
- 샤드 간 데이터 분포가 균등하지 못할때 특정 샤드는 샤드 소진
shard exhausition
이라고 부르는 현상
- 유명인사
celebirity
문제- 핫스팟 키 문제라고도 하며 특정 샤드에 질의가 집중되어 서버에 과부하가 걸리는 문제
- 조인과 비정규화
- 여러 샤드로 쪼개지면 데이터를 조인하기 힘들다 -> 데이터베이스를 비정규화
정리
- 시스템 규모를 확장하는 것은 지속적이고 반복적
iterative
한 과정을 거친다. - 시스템 규모 확장을 위해 살펴본 기법
- 웹 계층은 무상태 계층
- 모든 계층에 다중화 도입
- 가능한 한 많은 데이터를 캐시할 것
- 여러 데이터 센터를 지원할 것
- 정적 콘텐츠는 CDN을 통해 서비스 할 것
- 데이터 계층은 샤딩을 통해 그 규모를 확장할 것
- 각 계층은 독립적으로 서비스로 분할할 것
- 시스템을 지속적으로 모니터링하고, 자동화 도구들을 활용할 것