반응형

가상 면접 사례로 배우는 대규모 시스템 설계 기초를 공부하고 요약 정리한 글입니다

단일 서버

복잡한 시스템을 만드는 것도 간단한 시스템부터 차근차근 접근해 나가면 좋습니다.

모든 컴포넌트가 단 한대의 서버에서 실행되는 간단한 시스템부터 설계해 봅시다.

  1. 사용자는 도메인 이름을 사용하여 웹사이트에 접속합니다. 이 접속을 위해선 도메인이름을 IP로 변환하는 작업이 필요한데 그것을 DNS가 해줍니다
  2. DNS 조회 결과 IP 주소가 반환됩니다.
  3. 해당 IP 주소로 HTTP 요청이 전달됩니다
  4. 요청을 받은 웹서버는 HTML 페이지나 JSON 형태의 응답을 반환합니다

 

 

데이터베이스

사용자가 늘면 서버 하나로 충분하지 않아서 여러 서버를 두어야 합니다.

하나는 트래픽 처리 용도이고, 하나는 DB연산용입니다.

트래픽 처리 서버(웹 계층)과 데이터베이스 연산용 서버(데이터 계층)을 분리하면 각각 추후에 독립적으로 확장해 나갈 수 있습니다.

비 관계형 데이터베이스가 바람직한 선택일 케이스

  • 아주 낮은 응답 지연시간 요구됨
  • 다루는 데이터가 비정형이라 관계형데이터가 아님
  • 데이터를 직렬화하거나 역직렬화 할 수 있기만 하면 됨
  • 아주 많은 양의 데이터를 저장할 필요가 있음

 

 

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

스케일 업이라고 말하는 수직적 규모 확장 프로세스는 고사양 자원을 추가하는 것을 뜻합니다.

반면 스케일 아웃이라고 하는 수평적 규모 확장 프로세스는 더 많은 서버를 추가하여 성능을 개선하는 것을 말합니다.

서버로 유입되는 트래픽의 양이 적을 때 수직적 확장은 좋은 선택이 됩니다. 특히 이 방법의 가장 큰 장점은 단순함입니다.

그러나 스케일 업 방법에는 몇 가지 단점이 있습니다.

  • 수직적 규모 확장에는 한계가 있다. 한 대의 서버에 CPU나 메모리를 무한대로 증설할 방법은 없습니다.
  • 수직적 규모 확장법은 장애에 대한 자동복구 방안이나 다중화 방안을 제시하지 않습니다. 따라서 장애가 발생하면 완전히 중단됩니다.

위의 단점들로 인해서 대규모 애플리케이션을 지원하는 데는 수평적 규모 확장법이 적절합니다.

앞에서 살펴본 설계들은 웹 서버에 바로 연결되어서 웹 서버가 다운되면 사용자는 웹 사이트에 접속 할 수 없게됩니다.

따라서 이런 문제를 해결하는 데는 부하 분산기 또는 로드 밸런서를 도입하는 것이 최선입니다.

로드밸런서

사용자는 로드밸런서의 공개 ip주소로만 접근가능하며 각각의 서버는 사설 IP주소로 통신하기 때문에 사용자가 접근할 수 없습니다. 또한 서버의 갯수를 늘리게 되면 failover 처리 문제는 해소 되며, 웹 계층의 가용성도 향상됩니다.

데이터베이스 다중화

데이터베이스 다중화란 서버 사이에 주-부 관계를 설정하고 데이터 원본은 주 서버에, 사본은 부 서버에 저장하는 방식을 뜻합니다.

쓰기 연산은 마스터에서만 지원합니다. 부 데이터베이스는 사본을 주 데이터베이스로부터 전달 받고 읽기 연산만을 지원합니다. 보통 대부분의 애플리케이션은 읽기 연산의 비중이 쓰기 연산보다 훨씬 높습니다.

따라서 부 데이터베이스 갯수가 주 데이터베이스 갯수보다 많습니다.

데이터베이스를 다중화함으로 얻는 이점들

  • 더 나은 성능: 병렬로 처리되는 쿼리의 수가 늘어나므로 성능이 좋아집니다
  • 안정성: 데이터베이스 서버의 일부가 장애가 나도 데이터는 보존이 됩니다.
  • 가용성: 데이터를 여러 군데 복제해둠으로써 서버의 일부가 장애가 나도 다른 서버에 있는 데이터를 가지고 서비스를 지속할 수 있습니다.

데이터베이스 다중화까지 넣은 설계도는 아래와 같습니다

이 설계안은 다음과 같이 동작합니다.

  • 사용자는 DNS로부터 로드밸런서의 공개 IP주소를 받습니다.
  • 사용자는 해당 IP 주소를 사용해 로드밸런서에 접속합니다
  • HTTP 요청은 서버 1이나 서버 2로 전달됩니다
  • 웹 서버는 사용자의 데이터를 부 데이터베이스 서버에서 읽습니다.
  • 웹 서버는 데이터 변경 연산은 주 데이터베이스로 전달합니다. 데이터 추가, 갱신 연산 등이 이에 해당합니다

캐시

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

캐시계층

캐시 계층은 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠릅니다. 별도의 캐시 계층을 두면 성능이 개선될 뿐 아니라 데이터베이스의 부하를 줄일 수 있고, 캐시 계층의 규모를 독립적으로 확장시키는 것도 가능해집니다.

캐시 사용시 유의할점

  • 캐시는 어떤상황에 바람직한가? : 데이터 갱신은 자주 일어나지 않지만 참조는 빈뻔하게 일어난다면 고려해볼만 합니다
  • 어떤 데이터를 캐시에 두어야하는가?: 캐시는 데이터를 휘발성 메모리에 두므로, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않습니다.
  • 캐시에 보관된 데이터는 어떻게 만료되는가?: 이에 대한 정책을 마련해 두는 것이 좋은 습관입니다. 만료된 데이터는 캐시에서 삭제되어야 합니다. 만료기간이 너무 짧으면 데이터베이스 호출이 자주 일어날 것이고 너무 길면 원본과 차이가 날 가능성이 높아집니다
  • 일관성은 어떻게 유지되는가?: 일관성은 데이터 저장소의 원본과 캐시 내의 사본이 같은지 여부입니다. 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리 되지 않는 경우 이 일관성은 깨질 수 잇습니다.
  • 장애에는 어떻게 대처할 것인가?: 캐시 서버를 한 대만 둘 경우 해당 서버가 단일 장애 지점이 될 수 있습니다. 따라서 캐시 서버를 분산시켜야합니다.
  • 캐시 메모리는 얼마나 크게 잡을 것인가?: 캐시 메모리가 너무 작으면 액세스 패턴에 따라 데이터가 너무 자주 캐시에 밀려나버려서 성능이 떨어지게 됩니다. 이를 막을 한 가지 방법은 캐시 메모리 과할당이 있습니다
  • 데이터 방출 정책은 무엇인가?: 캐시가 꽉찼을때 기존 데이터를 내보내는 정책입니다. 이 정책은 가장 널리 쓰이는 것으 LRU알고리즘이 있고 LFU나 FIFO알고리즘도 있습니다.

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기