나 JAVA 봐라

[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 1장 사용자 수에 따른 규모 확장성 본문

DevOps, MLOps/독서

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

cool_code 2024. 5. 31. 00:45

1장 사용자 수에 따른 규모 확장성 

하나의 서버 내에 웹 앱, DB, 캐시 등이 다 있을 수 있지만, 사용자 수가 많아짐(요구 사항)에 따라 각각의 서버(웹, DB, 캐시,... 등)로 분리할 수 있다.

 

웹 계층

    • 스케일 업(수직적 규모 확장) vs 스케일 아웃(수평적 규모 확장)
    • 스케일 업의 한계
      • 한 대의 서버에 CPU, 메모리를 무한대로 증설하는 데에 한계가 있다. 
      • 장애에 대한 자동복구(failover), 다중화 방안 없기에 장애 발생 시 서비스가 중단된다.
      • -> 이런 단점으로 인해, 대규모 애플리케이션 지원하는데에는 스케일 아웃 많이 씀.
    • 로드 밸런서
      • 사용자 많을 때 부하 분산함.
      • 사용자는 로드밸런서의 공개 IP 주소로 접속(웹서버-클라이언트가 직접 연결 x) -> 로드밸런서가 사설 IP주소로 웹 서버 접속
      • 서버 간 통신에서는 사설 IP 주소 사용(같은 네트워크에 속한 서버 사이의 통신에만 사용 가능
      • 서버가 2대 이상일 때, 한 대가 다운된다면 다른 서버가 처리할 수 있기에 서비스 전체가 다운되지 않는다.
      • 만약 감당할 없는 트래픽이 없으면, 간단하게 서버를 추가하면 로드밸런서가 자동적으로 트래픽을 분산한다
  •  

데이터베이스 계층

  • DB 다중화 (replication) : 쓰기(create, delete,…) , 읽기(get) 연산에 따라 master-slave로 나눌 수 있음. -> 대부분의 애플리케이션은 읽기 연산이 훨씬 많기 때문에 slave DB가 더 많다. 
  • DB 다중화 하는 이유? 
    • 성능 : 요청 (쓰기, 읽기)에 따라 알맞은 DB가 처리하기에 병렬로 처리할 수 있는 질의 (query) 수가 늘어남.
    • 안정성 : DB 일부가 파괴되어도 replication했기에 데이터를 보존할 수 있음. 가용성 : DB 일부에 장애가 생겨도 다른 DB를 사용하기에 계속 서비스를 사용할 수 있음.

캐시 계층

    • 응답 시간 (latency) 줄이기 위해 사용하며, 정적 콘텐츠를 CDN으로 옮겨 개선할 수 있음. 
    • 애플리케이션 성능은 DB를 얼마나 자주 호출하냐에 따라 크게 좌우되기에, 캐시를 통해 성능을 개선할 수 있다. 
    • 보통 캐시도 데이터를 API 형식으로 주고받기에 사용이 편리하다. 
    • 캐시 유의할 점
      • 데이터의 변경이 자주 일어나면, 캐시 데이터와의 일관성이 없기에 변경이 많이 없는 데이터를 캐싱한다. 
      • 캐시 데이터의 만료 시점을 정해야한다. -> 만료 시점이 길면 원본과 차이가 클 수 있고, 짧으면 DB를 너무 자주 접근할 수 있다
      • 캐시 메모리가 너무 작으면 데이터가 너무 자주 캐시에서 밀려나버려 캐시 서버의 의미가 없을 수 있기에, 캐시 메모리를 과할당하여 방지할 수 있다. 
      • 캐시 메모리가 상태에서 데이터를 추가로 넣으려면 데이터를 방출해야하는데 LRU, FIFO,… 등의 데이터 방출 정책을 적용할 있다. 
      • 단일 캐시 서버의 경우 SPOF 발생할 수 있기에 캐시 서버도 분산해야한다. 
      • 캐시는 휘발성 데이터이기에, 중요한 데이터는 지속적 저장소에 두어야한다. 
    • CDN : 정적 콘텐츠를 전송하는 쓰이며, 지리적으로 분산된 서버의 네트워크

무상태 웹 계층

  • 웹 계층을 ‘수평적’으로 확장하기 위해 상태 정보 (샤용자 세션)를 웹 계층에서 제거해야한다. 
    • 상태 정보를 보관하면, 인증 정보가 서버 1에 있을 때, 서버 1로만 계속 연결되어야 한다. -> 즉 같은 클라이언트는 같은 서버로만 라우팅 되어야 한다.
      • 로드 밸런서에서 스티키 세션 기능을 제공하지만, 로드 밸런서에 부담을 주고, 새로운 서버를 제거, 생성하는 것도 복잡해진다. 
  • 만약 웹 서버에서 세션 정보를 저장해야한다면, 공유 저장소를 두는 것이 대규모 시스템에 더 적합하다. 

데이터 센터

  • 가용성 높이기 위해 여러 데이터 센터를 두는 것이 필요하다. 
  • 장애 없는 상황에서는 지리적 라우팅을 통해 제일 가까운 데이터 센터로 접속한다. 반면, 장애가 발생했을 경우, 장애 없는 데이터 센터로 전송된다.
  • 다중 데이터센터 아키텍처의 기술적 난제
    • 트래픽 우회 : 올바른 데이터 센터로 트패픽을 보내는 효과적인 방법을 채택해야 함.
    • 데이터 동기화 : 데이터 센터마다 별도의 DB 두는 경우, 장애가 자동 복구 되어서 다시 다른 데이터 센터로 접속한다면 해당 데이터 센터에는 찾는 데이터가 없을 수 있다. -> 데이터를 여러 데이터센터에 걸쳐 다중화하는 것이 필요함 (넷플릭스 다중화 전략 참고)
    • 테스트와 배포 : 웹 사이트, 애플리케이션이 여러 위치(데이터 센터)에서 잘 작동하는지 테스트하는 것이 필요하다. 자동화된 배포 도구가 있다면 동일한 서비스 설치되도록 하는데 중요한 역할을 한다. 

메시지 큐

  • 메시지 큐 : 데이터 무손실 보장하고, 비동기 통신을 지원하는 컴포넌트
  • Producer -> subscriber 
  • 서버 결합 느슨해지기에, 규모 확장성 보장되어야 하는 안정적 애플리케이션을 구성하는 데에 좋다. 

로그, 메트릭, 자동화

  • 로그 : 에러 로그 모니터링하여 시스템 오류 찾아낸다. 서버 단위로 모니터링할 수도 있지만, 여러 서버의 로그를 단일 서비스로 모아주는 도구를 활용할 수도 있다. 
  • 메트릭 : 메트릭을 수집하여 사업 현황에 관한 유용한 정보를 얻거나, 시스템의 상태를 파악할 수 있다. 
    • Ex) CPU, 메모리, 디스크I/O, MAU, DAU, 재방문, DB 계층 성능, 캐시 계층 성능 등
  • 자동화: 생산성 높이기 위해 자동화 도구 활용
    • Ex) CI 도와주는 도구 활용하여 개발자 코드를 자동으로 검증할 수 있도록 한다. (+ 빌드. 테스트, 배포 자동화 가능)

 

DB 규모 확장

      1. 수직적 확장 
        • CPU, RAM 등의 하드웨어를 무한 증설할 수 없다
        • SPOF로 인한 위험성이 크다
        • 고성능 서버로 수록 비용이 크다
      2. 수평적 확장 (= sharding)
        • 샤딩: 대규모 DB를 샤드라는 작은 단위로 중복 없이 분할하는 기술
        • 데이터를 어느 샤드에 둘지는 샤딩 키(=파티션 키)로 결정함. 샤딩 키는 데이터가 골고루 분포되도록 정해야 한다.
        • 샤딩 도입 시 고려할 문제
          • 데이터의 재 샤딩
            • 데이터가 너무 많아져서 하나의 샤드로는 감당하기 어렵거나, 샤드 간 데이터 분포가 균등하지 못하여 샤드 소진 현상이 날 경우에 필요하다.
            • 샤드 키를 계산하는 함수를 변경하여 데이터를 재배치해야하는데, 안정 해시 기법을 활용할 수 있다.
          • 유명인사 문제 (= 핫스팟 키 문제)
            • 특정 샤드에 질의가 집중되어 서버에 과부하가 걸리는 문제. 
            • Ex) 차은우, 손흥민,…~ 같은 유명인사가 전부 같은 샤드에 저장되어 많은 read 연산으로 인한 과부하 발생
          • 조인과 비정규화
            • 하나의 DB 여러 샤드 서버로 쪼개고 나면, 여러 샤드에 걸친 데이터를 조인하기가 힘들어진다. -> 해결 위해 DB 비정규화하여 하나의 테이블에서 질의가 수행되도록 한다

정리

  • 웹 계층은 무상태 계층으로 
  • 모든 계층에 다중화 도입
  • 가능한 한 많은 데이터 캐시
  • 여러 데이터 센터 지원
  • 정적 콘텐츠는 CDN을 통해 서비스
  • 데이터 계층은 샤딩을 통해 규모를 확장
  • 각 계층은 독립적 서비스로 분할
  • 시스템을 지속적으로 모니터링, 자동화 도구 활용