가상 면접 사례로 배우는 대규모 시스테 설계 기초 #1(사용자 수에 따른 규모 확장성)

박주진·2021년 8월 28일
1

가상 면접 사례로 배우는 대규모 시스테 설계 기초를 읽고 정리한 내용입니다. 자세한 부가설명이 궁금하시면 보시는걸 추천드립니다.

규모가 증가함에 따라 단계적으로 구조를 변경해가는 과정입니다.

1단계 - 웹 앱, 데이터베이스, 캐시 모두 서버 한대인 구조

2단계 - 웹/모바일 트래픽 처리 용도, 데이터 처리 용도로 서버 분리

어떤 DB를 선택해야 할까? 🙄 (관계형 데이터베이스(RDB) VS 비 관계형 데이터베이스(NoSQL))

대부분 상황에서는 RDB가 좋은 선택이다. 하지만 아래와 같은 경우는 비 관계형 데이터베이스를 고려하여야 한다.

  • 아주 낮은 응답지연시간 요구
  • 비정형 데이터
  • 데이터의 직렬화 또는 역직렬화만 필요
  • 대규모 데이터 저장 필요

3단계 - 트래픽 분산을 로드 밸런서 적용

보통 위와 같은 scale out 방식으로의 확장을 선택하는 이유는 아래와 같은 scale up의 치명적인 단점 때문이다.

  • CPU, 메모리를 무한대 증성 불가
  • 장애에 대한 자동복구(failover) 및 다중화(redeundancy)에 대한 방안이 없어 장애시 서버 완전 중단

하지만 서버로 유입되는 트래픽 양이 많지 않다면 단순함이 장점인 scale up 방식도 좋은 선택이다.

위와 같은 구조에서는 자동복구 문제도 해소되고 가용성(availability)도 향상된다. 그 이유는 아래와 같다.

  • 서버1이 죽으면 로드 밸런서가 모든 트래픽을 서버2로 전송한다. 이로써 전체 장애는 방지된다.
  • 트래픽이 증가하여 2대의 서버로도 감당못할 시점이 오면 웹서버를 추가한다. 그러면 로드 밸런스가 자동적으로 트래픽을 분산시켜 주어 증가한 트래픽에 손쉽게 대응이 가능하다.

4단계 - 데이터 베이스 다중화 적용

데이터 베이스 다중화 장점

  • 성능 향상
    읽기 연산과 변경 연산이 분산되어 병렬로 여러 쿼리를 처리할 수 있음
  • 안정성
    지역적으로 다른 곳에 데이터를 보관할 수 있음으로 일부 데이터 베이스 파괴시 데이터 보존 가능
  • 가용성
    데이터가 여러 지역에 복제되어 있어 특정 데이터 베이스 장애시 다른 서버의 데이터로 서비스 운영 가능

데이터 베이스 다중화로 아래와 같은 상황을 감당할 수 있다.

  • slave 서버 다운된 경우
    다른 slave 서버 또는 master 서버가(다른 slave 서버가 없다면) 요청 처리 -> 새로운 slave 서버가 장애서버 대체
  • master 서버 다운된 경우
    slave중 한대가 master서버 대체 -> 새로운 slave 서버가 장애서버 대체
    실제로는 master 서버 다운시 slave 서버에 보관된 데이터가 최신이 아닐 수 있어 훨신 복잡하다. 그럼으로 다중 마스터 또는 원형 다중화 방식 도입이 필요.

5단계 - CDN 및 캐시 적용

캐시란?

  • 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 이후 요청이 빨리 처리될 수 있도록 하는 저장소
  • 데이터베이스를 얼마나 덜 호출하느냐가 어플리케이션의 성능을 크게 좌우하기 때문에 캐시를 사용해 DB호출을 줄일 수 있다.

캐싱 전략

이부분은 책에서는 자세히 언급되어 있지 않아 따로 정리하였습니다.

  • Cache-Aside

캐시에 있으면 캐시에서 조회하고 없으면 DB를 조회한 후 데이터를 캐시에 로드하는 방식

  • 단점

    • 캐시 데이터는 DB데이터와 일관성이 깨질 수 있다.(TTL방식과 같은 Cache invalidation strategies 채택 또는 다른 쓰기 캐시전략 을 택해야 함)
  • 장점

    • 캐시가 죽어도 DB를 조회하기 때문에 캐시서버 장애에도 서비스 운영이 가능하다.
    • 데이터 모델을 DB와 다르게 유지할 수 있다.
    • 읽기가 많은 작업에 적합하다.
    • 캐시 데이터는 DB데이터와 일관성이 깨질 수 있다.
  • Read-Through

    캐시에서 데이터를 조회하고 데이터가 없으면 캐시 솔루션이 데이터를 DB로 부터 가져온 후 응답하는 방식.

    • 장점
      • 동일한 데이터를 여러번 읽기하는 작업에 적합하다.
    • 단점
      • 데이터 모델을 DB와 다르게 유지할 수 없다.
      • 처음에는 무조건 cache miss가 일어나기 때문에 초기에는 (‘warming’ or ‘pre-heating’)과 같은 작업이 필요할 수 있다.
      • 캐시 데이터는 DB데이터와 일관성이 깨질 수 있다.
  • Write-Through

    캐시에 데이터를 쓰면 캐시가 즉시 DB에 데이터를 쓰는 방식

    • 장점
      • 별도의 cache invalidation strategy없이도 read-through 방식과 같이 사용하면 데이터의 일관성을 보장할 수 있다.
    • 단점
      • 쓰기 작업시 대시 시간이 추가된다.
  • Write-Back

    캐시에 데이터를 쓰고 일정 기간이후 캐시가 DB에 데이터를 쓰는 방식

    • 장점
      • DB 장애에 대응이 가능
      • DB 부하를 줄일 수 있다.
      • 대용량 쓰기 작업에 적합하다.
      • read-through 방식과 같이 사용하면 데이터의 일관성을 보장할 수 있다.
    • 단점
      • 캐시 장애시 데이터가 유실 가능성이 있다.
  • Write-Around
    DB에다가 직접 바로 쓰는 방식. 보통 Cache-aside 또는 Read-Through 방식과 같이 사용된다.

자세한 내용은 링크를 참고해 주세요.

캐시 사용시 유의할점

  • 어떤 상황이 적절할까? (데이터 갱신은 자주 일어나지 않고 참조만 빈번한 상황)
  • 어떤 데이터를 캐시에 두어야 할까? (캐시의 데이터는 휘발될 여지가 있기 때문에 영속적으로 보관할 데이터는 지속적 저장소에 두어야 한다.)
  • 만료 정책 (만료기한이 너무 짧으면 데이터 베이스 호출이 증가하고 너무 길면 원본과의 정합성이 차이가 날 가능성이 높다)
  • 일관성은 어떻게 유지? (저장소 원본은 갱신하는 작업과 캐시를 갱신하는 작업이 단일 트랜잭션으로 처리 되지 않으면 깨질수 있다. 하지만 시스템 확장시 이를 유지하는것 어렵다. 개인적인적으로 조사한 바에 따르면 정확한 정합성을 위해서는 write 와 read cache를 같이 사용해야 지켜질 것 같다.)
  • 장애에 어떻게 대처? (spof를 피하기 위해 캐시 서버를 한대 이상으로 분산시켜야 한다.)
  • 캐시 메모리 크기
  • 데이터 방출 정책 (LRU, LFU, FIFO)

CDN이란?

  • 정적 콘텐츠(image,video, css, js)를 캐싱하는데 사용된다.
  • 사용자에게 지리적으로 가장 가까운 CDN 서버가 정적 콘텐츠를 전달한다.

CDN 사용시 고려할 사항

  • 비용 (보통 데이터 전송양에 따라 요금이 부과 된다.)
  • 적절한 만료 기간 (캐시와 동일하게 너무 짧으면 원본서버에 빈번하게 접속하고 길면 콘테츠 신선도가 떨어진다.)
  • CDN 장애 대처 방안 (가령 CDN서버가 죽으면 원본서버에 접근하도록 구성이 필요하다.)
  • 콘텐츠 무효화 방법 (CDN 사업자가 제공하는 api사용 또는 오브젝트 버저닝 사용(imge.png?v=2))

6단계 - 무상태(stateless)웹 계층 적용 (세션 스토리지 분리)

상태를 유지할때의 문제점

상태 정보(세션데이터)를 웹계층에서 분리하지 않고 웹서버에서 보관하게 되면 아래와 같이 클라이언트는 항상 같은 서버로 요청이 전달되어야 한다.

이런 문제점을 해결하기 위해 여러가지 방법이 있다.(책에서는 자세히 다루고 있지 않아 추가해서 정리하였습니다.)

  • 로드밸런서의 sticky session
    사용자의 세션을 로드밸런서에서 처음 생성된 서버에 바인딩하여 이후 동일한 사용자로부터 들어오는 모든 요청을 동일한 서버로 보내는 것이다.
    하지만 아래와 같은 문제점이 존재합니다.
    - 특정 서버에 트래픽이 몰릴 수 있다.
    - 세션 정보가 사라질 수 있다. (특정 웹서버가 다운되거나 종료하면 세션정보도 같이 사라진다.) 즉 서비스중 웹서버를 추가하거나 제거하기 까다로워진다.

  • Session Clustering
    여러 서버에 흩어져 있는 세션 데이터를 하나의 그룹으로 묶어 관리하는 것입니다. WAS에 따라 그 방법이 다르다. Tomcat에서는 all-to-all 세션 복제 방식을 사용하고 있으며, 이는 각 서버에서 생성된 모든 세션들을 클러스터로 묶인 서버에 복제하는 방식이다.
    하지만 아래와 같은 문제점이 존재합니다.
    - 서버가 늘어날 수록 복제해야하는 데이터양과 횟수가 늘어난다.

  • 세션 스토리지 분리
    새로운 저장소에서 세션정보를 담아두고 공유하는 방식이다. 이 방식은 앞서 소개된 두 방식에 비해 아래와 같은 장점이 있다.

    • 외부 세션 저장소 정보만 알고 있으면 되기 때문에 손쉽게 웹서버를 추가 및 제거가 가능하다.
    • 특정 서버에 트래픽이 몰릴 위험이 없다.
    • 세션 데이터 공유를 위해 데이터 복제가 불필요하고 정합성 이슈도 없다.

하지만 데이터 유실에 대비하기 위해서는 세션 저장소에 대한 클러스터링을 별도로 진행해야 한다.

6단계 - 멀티 데이터 센터 지원

전세계 어디에서든 쾌적하게 사용할 수 있게 여러 데이터 센터를 지원해야 한다.

지리적 라우팅을 통해 사용자의 위치에 따라 도메인 이름을 가장 가까운 데이터 센터 IP로 변환하여 서비스 한다. 데이터 센터 하나가 장애가 발생하면 다른쪽으로 트래픽을 돌릴 수 있는 장점이 있다.

기술적 난제

  • 트래픽 우회 (올바른 데이터 센터로 트래픽을 보내는 가장 효과적인 방법이 필요)
  • 데이터 동기화 (데이터 센터마다 별도의 데이터베이스를 사용한다면 이를 어떻게 동기화 할 것인가? 어떻게 여러 데이터 센터에 걸쳐 다중화를 할 것인가?)
  • 테스트 배포 (어떻게 여러 데이터센터에 동일하게 서비스를 배포 할 것이며 여러 위치에서 어떻게 테스트 할 것인가?)

🙄언제 이정도 까지의 확장이 필요할까? 전세계에 서비스하는 정도로 커지면 필요할까?? 클라우드 환경에서도 필요한걸까?

7단계 - 메세지큐, 로그, 메트릭, 자동화 반영

메세지 큐는 메세지 무손실, 비동기 통신, 서버간에 결합도 감소, 규모 확장성 등의 이유로 사용한다. 로그,메트릭,CI/CD 또한 서비스 규모가 커지면 개발 생산성 향상을 위해 필수적으로 구축해야 한다.

8단계 - 데이터베이스 규모 확장

수직적 확장 vs 수평적 확장

데이터가 많아 지면 데이터 베이스를 증설해야 한다. 그때 두가지 방법중 하나를 선택해야 한다.

  • 수직적 확장 (CPU,RAM, 디스크 등 을 증설하는 방법)
    하지만 아래와 같은 단점이 존재한다.
    - 하드웨어 증설은 한계가 존재한다.
    - 단일장애 포인트 이다.
    - 비용이 많이든다.
  • 수평적 확장 (여러 서버에 데이터를 분산해서 저장하는 방법)
    보통 샤딩이라고 부르며 같은 테이블 스키마를 가진 데이터를 다수의 데이터베이스에 분산하여 저장하는 방법이다.
    데이터를 고르게 분할 할 수 있도록 샤딩 키를 어떻게 정하느냐 관건이다.
    하지만 샤딩을 도입하면 아래와 같은 문제가 생긴다.
    - 데이터의 재 샤딩 (데이터 분포가 균등하지 못하여 특정 샤드의 저장 공간이 다른 샤드에 비해 빠르게 소진 된다. 그러면 샤드 키 계산 방법을 변경해야 하고 데이터를 재배치하여야 한다.)
    - 유명인사 문제 (특정 샤드에 질의가 집중되는 문제로써 해결법은 더 잘게 샤드를 쪼개거나 자주 조회되는 데이터를 샤드별로 분리해야 한다.)
    - 조인과 비정규화 (여러 샤드에 걸친 데이터를 조인하기 힘들다.이를 해결하는 방법은 데이터베이스를 비정규화하여 하나의 테이블에서 질의 되도록 해야 한다.)

추가적인 reference

0개의 댓글