728x90
단일서버
- 웹,앱, 데이터베이스, 캐시 등이 모든 리소스들이 전부 서버 한대에서 실행된다.
- DNS를 통해 해당 도메인의 IP주소를 요청한다.
- DNS는 해당 도메인 주소의 IP를 반환한다.
- 해당 IP 주소로 HTTP 요청이 전달된다.
- 요청을 받은 웹 서버는 응답을 반환한다.
데이터베이스
사용자가 늘어나면 부하 분산을 하기 위해 여러 서버를 두어야 한다. 단말기에서 오는 요청을 처리하는 서버인 웹 계층과 데이터베이스 서버인 데이터 계층으로 분리하여 독립적으로 확장할 수 있게 한다.
- 데이터베이스의 종류는 관계형 데이터베이스와 비-관계형 데이터베이스가 있다. 자세한 내용은 아래를 참고하세요.
수직적 규모 확장(Scale Up) vs 수평적 규모 확장(Scale Out)
- 수직적 규모 확장(Scale Up)은 고사양 자원을 추가하여 성능을 개선하는 행위.
- 수평적 규모 확장(Scale Out)은 더 많은 서버 갯수를 추가하는 행위.
- 수직적 규모는 SROF가 될 수 있으며, 한계가 있고, Failover나 다중화 방안이 없기 때문에 수평적 규모 확장을 권장한다.
로드밸런서
- 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.
- 공개 IP로 되어 잇는 로드밸런서로 사용자는 접속하고, 로드밸런서가 보안을 위해 서버 간 통신을 prviate IP로 해두어 통신을 하게 된다.
- 이렇게 되면 부하 분산 집합에 또 하나의 웹 서버를 추가하면 failover의 문제가 해결되며 웹 계층의 가용성은 향상된다.
- 서버 1이 다운되면 모든 트래픽은 서버 2로 전송된다. 따라서 웹 서버 전체가 다운되는 일이 방지된다. 부하를 나누기 위해서 새로운 서버 추가도 가능
- 웹 사이트로 유입되는 트래픽이 가파르게 증가하면 두 대의 서버로 트래픽을 감당할 수 없을수 있다. 이때 로드밸런서가 있기 때문에 웹 서버 계층에 많은 서버를 추가하기만 하면 된다. 그러면 로드밸런서가 자동으로 트래픽 분산을 함.
데이터베이스 다중화
- 데이터베이스도 Master-Slave 관계로 설정해 다중화가 가능하다.
- 쓰기 연산은 Master / 읽기 연산은 Salve에서 가능하게 한다.
- 대부분의 애플리케이션은 읽기 연산이 쓰기 연산보다 훨씬 비중이 높다. 따라서 통상 Slave 데이터베이스가 더 많다.
장점
- 더 나은 성능
- 병렬로 처리될 수 있는 Query의 수가 늘어나므로 성능이 좋아진다.
- 안정성 및 가용성
- 데이터베이서 서버 가운데 일부가 문제가 생겨도 다른 서버에서 받으면 되니 데이터 유실이나 전체 장애로 가진 않는다.
데이터베이스 서버의 하나가 다운되면?
- Slave가 한대인 경우에 다운되면 Master로 모두 전달되도록 하면 된다.
- Master가 다운 되면 Slave로 처리하면 된다. 그러나 이때 Slave는 최신 상태가 아닐수 있기 때문에 복구 스크립트, 다중 마스터, 원형 다중화 등 방법들을 도입을 고려해봐야 한다.
캐시
- 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 처리하는 저장소며, 임시저장소로 많이 쓰이며 데이터베이스보다 훨씬 빠른 장점을 가지고 있다.
캐시 사용시 유의할 점
- 캐시는 어떤 상황에 바람직 한가?
- 데이터 갱신은 자주 일어나지 않지만 참조는 빈번하게 일어난다면 고려해볼 만 하다
- 어떤 데이터를 캐시에 두어야 하는가?
- 캐시는 데이터를 휘발성 메모리에 있으므로, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다.
- 캐시에 보관된 데이터는 어떻게 만료 되는가?
- 만료 기한을 설정해두는 습관이 필요하다. 만료 기간이 짧으면 데이터베이스에서 자주 읽게 되며, 너무 길면 원본과 차이날 가능성이 높다. 적절한 시간을 정책으로 정하는 것이 중요하다.
- 일관성(원본과 캐시된 사본과 같은가?)은 어떻게 유지되는가?
- 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리되지 않는 경우 이 일관성은 깨질 수 있다. 여러 지역에 걸쳐 시스템을 확장해 나가는 경우 캐시와 저장소 사이의 일관성을 유지하는 것은 어려운 문제가 된다.
- 장애에는 어떻게 대처할 것인가?
- 캐시 서버를 한 대만 두는 경우 해당 서버는 단일 장애 지점이 될 가능성이 있다. 캐시 서버 분산이 필요하다.
- 캐시 메모리는 얼마나 크게 잡을 것인가?
- 캐시 메모리가 너무 작으면 엑세스 패턴에 따라서는 데이터가 너무 자주 캐시에서 밀려나버려 캐시의 성능이 떨어진다. 이 문제를 해결 하는 것은 캐시 메모리를 과할당 하는 것이다.
- 데이터 방출 정책은 무엇인가?
- 캐시 데이터 방출 정책을 정저의해야 한다. 가장 널리 쓰이는 것은 LRU이다. 다른 정책으로는 LFU나 FIFO 같은 것도 있으며, 경우에 맞게 적용하면 된다.
CDN
- 정적 콘텐츠를 전송하는 데 쓰이는 지리적으로 분산된 서버 네트워크다. 요청 경로, Query String, 쿠키, 요청 헤더 등의 정보를 기반하여 정
- CDN은 사용자가 웹 사이트를 방문하면, 그 사용자에게 가장 가까운 CDN 서버가 정적 콘텐츠를 전달하게 된다., CDN 서버로부터 멀면 멀수록 웹사이트는 천천히 로드된다.
- 사용자가 정적 콘텐츠를 호출한다.
- CDN 서버의 캐시에 해당 이미지가 없는 경우 서버는 원본 서버에 요청하여 가져온다.
- 원본 서버가 파일을 CDN 서버에 반환한다. 응답의 HTTP 헤더는 TTL 값이 있다.
- CDN 서버는 파일을 캐시하고 사용자 에게 반환한다. 이미지는 TTL에 명시된 시간이 끝날 떄까지 캐시된다.
- 사용자가 같은 이미지에 대한 요청을 CDN 서버에 요청한다.
- 만료되지 않은 이미지에 대한 요청은 캐시를 통해 처리된다.
CDN 사용시 고려해야 할 사항
- 비용
- 적절한 만료 시한 설정
- 너무 길면 콘텐츠의 신선도는 떨어지고, 너무 짧으면 서버에 빈번이 접속하게 되어서 좋지 않다.
- CDN 장애에 대한 대처 방안
- 장애가 발생하면 원본 서버로부터 직접 콘텐츠를 가져오도록 클라이언트를 구성해야 할 수 있다.
- 콘텐츠 무효화 방법
- CDN 서비스 사업자가 제공하는 API의 콘텐츠 무효화
- 콘텐츠의 다른 버전을 서비스 하도록 오브젝트 버저닝 이용.
무상태(stateless) 웹계층
상태 정보 의존적인 아키텍처
- 각 서버마다 사용자의 상태를 가지고 있다면, 해당 사용자는 자기 자신이 가지고 있는 상태가 존재하는 서버로만 접근해야 한다. 이부분에서 가장 큰 문제가 사용자는 매번 같은 서버로만 요청을 보내야 한다는 것이다. 이걸 로드밸런서에서는 “고정 세션 기능”을 제공하지만 로드밸런서에 부하를 주는 행위이며, 서버를 추가하거나 제거할때 문제가 발생할 수 있다.
무상태 아키텍처
- 상태 정보가 저장되어 있는 공유 저장소를 만들어 데이터를 가져오게 한다. 이러면 웹 서버로부터 분리되어 단순하고 안정적이 된다.
데이터 센터
- 장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내받는 지리적 라우팅이 된다.
- 이때 데이터 센터 하나가 장애가 발생한다고 하면 아래와 같이 될것이다.
기술적 난제
- 트래픽 우회
- 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 한다.
- 데이터 동기화
- 데이터센터마다 별도의 DB를 가지고 있다면 장애가 failover되었을때 데이터베이스도 같이 복.그되러데. 이때 데이터가 존재하지 않을 수 있다. 이런 상황을 막는 법은 데이터센터에 걸쳐 다중화하는것이다.
- 테스트와 배포
- 여러 데이터 센터를 사용하도록 시스템이 구성되어 있는 상황이라면 웹 사이트 또는 웹 애플리케이션을 여러 위치에서 테스트 해보는 것이 중요하다.
- 자동화된 배포 도구는 모든 데이터 센터에 동일한 서비스가 배포되도록 해야 한다.
메시지 큐
- 메시지의 무손실(메시지 큐에 일단 보관된 메시지는 소비자가 꺼낼 떄까지 안전히 보관된다는 뜻)을 보장하는 비동기 통신을 지원하는 컴포넌트다. 메시지 버퍼 역할을 하며, 비동기적으로 전송한다.
기본 아키텍처
- 생산자 또는 발생자라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발생한다. 큐에는 보통 소비자 혹은 구독자라 불리는 서비스 혹은 서버가 연결되어있는데 메시지를 받아 그에 맞는 동작을 수행하는 역할을 한다.
- 메시지 큐를 이용하면 서비스 또는 서버 간 결합이 느슨해져서 규모 확장성이 보장되어야 하는 안정적 애플리케이션을 구성하기 좋다.
로그, 메트릭 그리고 자동화
- 로그
- 에러 로그를 모니터링 하는 것이 중요하다. 시스템 오류와 문제들을 보다 쉽게 찾아낼 수 있도록 하기 때문.
- 메트릭
- 호스트 단위로는 CPU, 메모리, 디스크 IO 등이 필요하며 종합적인 부분에선 DB 계층의 성능, 캐시 계층의 성능 등이 필요하며 비지니적인 부분은 DAU, 수익, 재방문 같은 데이터가 필요하다.
- 자동화
- CI를 이용해 테스트, 빌드를 자동화하고 배포 자동화를 통해 개발자 생산성을 높이는 것을 의미한다.
데이터베이스의 규모 확장
수직적 확장(Scale Up)
- Scale Up의 문제는 위에서와 같이 한계가 존재하며 SROF로 인한 위험성과 비용이 많이 든다.
수평적 확장(Sharding)
- 대규모 데이터바이스를 샤드라고 부르는 작은 단위로 분할해 각 샤드로 같은 스크마로 보관되지만 각 중복되지 않는 데이터를 저장하는 방식이다.
- 예를들어 user_id를 4로 나누는 해시 함수를 사용해 각 샤드에 저장하게 한다. 여기서 user_id는 샤딩 키가 되고 데이터가 어떻게 분산될지 정하는 컬럼을 의미한다.
- 샤딩 키를 통해 올바른 데이터베이스에 Query를 호출해 효율을 높여야 한다.
- 샤딩을 도입하면 시스템이 복잡해지고 문제가 생기는 부분이 있다.
- 데이터의 재샤딩으로 데이터가 많아져서 하나의 샤드로 더이상 감당이 안되거나 샤드 간의 데이터 분포가 균등하지 못해 특정 샤드에 할당된 공간 소모가 다른 샤드에 비해 빠르게 진행될때 샤드 키를 계산하는 함수를 변경하고 재 배치를 해야 한다. 이때 안정 해시 기법을 활용하면 문제가 해결된다.
- 유명인사 문제(=핫스팟 키 문제)라고 하는 특정 샤드에 Query가 집중되어 해당 샤드 서버에 과부화가 걸리는 문제가 있다. 이런 경우 재샤딩을 해야 할수 있다.
- 샤드 서버로 쪼개지면 여러 샤드에 걸친 데이터의 조인이 어려울수 있다. 이때 비정규화를 하거나 하나의 테이블에서만 Query가 수행될수록 해야 할 수 있디.
요약
- 웹 계층은 무상태 계층으로
- 모든 계층에 다중화 도입
- 가능한 한 많은 데이터를 캐시할 것
- 여러 데이터 센터를 지원할 것
- 정적 콘텐츠는 CDN을 통해 서비스할 것
- 데이터 계층은 샤딩을 통해 그 규모를 확장할 것
- 각 계층은 독립적 서비스로 분할할 것
- 시스템을 지속적으로 모니터링하고, 자동화 도구들을 활용 할것
책출처
728x90
728x90
'Book > 가상면접 사례로 배우는 대규모 시스템 설계' 카테고리의 다른 글
[가상면접 사례로 배우는 대규모 시스템 설계 vol.1] 2장. 개략적인 규모 측정 (0) | 2024.04.22 |
---|