가상면접사례로 배우는 대규모 시스템 설계 기초

오늘 배운 것

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

단일서버

데이터베이스

관계형, 비 관계형 = NoSQL이 있다.

어떤 DB를 사용할 것인가?

  • 관계형

    자료를 테이블과 열, 칼럼으로 구분한다. SQL을 사용하면 여러 테이블에 있는 데이터를 관계에 따라 join 할 수 있다.

  • 비관계형

    다시 4개 부류로 나누면

    키-밸류 store 그래프 store 칼럼 store 문서 store

로 나뉜다.

관계형 DB에 대해 다음과 같은 이점이 있다.

  1. 아주 낮은 응답 지연시간(Latency)가 요구됨 예를들어, MySQL은 데이터를 Disk에 저장하고, 버퍼 풀 같은게 있긴 하지만 dist 들리긴 한다. 반면 Redis는 메모리에서만 돌아가므로 훨씬 빠를것이다.
  2. 다루는 데이터가 비정형이라 관계형 데이터가 아님 MySQL은 스키마를 정해두고 정형데이터만 사용하지만, 새로운 데이터 칼럼이 추가되어 스키마 변경시, 대용량 테이블 기준으로 큰일난다. 인덱스가 무효화되고 테이블 풀스캔 및 기존 서비스 중단…
  3. 데이터(JSON, YAML, XML)를 직렬화 하거나, 역직렬화 할 수 있기만 하면 됨 JPA 같은 ORM이 겪는 자바 객체와 테이블의 미스매칭이 아예 없는 NoSQL (MongoDB)
  4. 아주 많은 양의 데이터를 저장할 필요가 있음 수평적 확장을 고려해야 할 때, MySQL은 샤딩을 해야 하는데, 이게 원래 제공하는 기능이 아니라 애플리케이션 단에서 하는거임. 하지만 카산드라 ,HBase같은 Col-family store, MongoDB는 설계 단계부터 수평확장을 염두에 두었다.

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

스케일 업 - 수직적 규모 확장, 서버의 부품 추가. 스케일 아웃 - 수평적 규모확장, 더 많은 서버

트래픽 양이 적다면 스케일 업이 유효하다. 가장 큰 장점은 단순함이다.

스케일 업의 단점

  • 한 대의 서버에 CPU, mem을 무한히 붙일수는 없다.
  • 장애에 대한 자동복구(failover)방안이나 다중화(redundancy)방안을 제공하지 않는다. 장애 발생시 서비스는 완전 중단된다.

로드밸런서

부하 분산 집합(load balancing set)에 속한 웹 서버들에게 트래픽을 고르게 분산한다.

사용자는 로드밸런서의 공개 IP주소에 접속한다. 서버간 통신에는 Private IP로 서로 통신한다.

로드밸런서를 추가하면 자동복구 = Failover가 가능해진다. 그리고 웹 계층의 가용성이 향상된다.

문제 발생시 부하 분산 집합에 서버를 추가하기만 하면 된다.

이제 웹계층은 해결, DB 는 여전히 하나인데 어떻게 할까.

데이터베이스 다중화

많은 DBMS가 다중화를 지원하며, 보통 주-부 관계를 두고 원본은 주, 사본을 부에 저장한다.

write, update는 주에만 하고 read는 부에다가 한다.

대부분의 애플리케이션은 read 비율이 2:8, 1:9 정도로 높다.

다중화의 이득은 다음과 같다.

  1. 더 나은 성능 : 연산이 분산되므로, 병렬로 처리될 수 있는 query의 수가 늘어나므로 성능이 좋아진다.
  2. 안정성(realiability) : DB 일부가 파괴되어도 데이터가 보존된다. 지역적으로 떨어진 여러 장소에 다중화 할 수 있기 때문.
  3. 가용성(availability) : 데이터를 여러 지역에 복제해두어서, 장애 발생 시 다른 서버 DB 로 서비스 지속 가능

앞절에서 로드밸런서는, 웹계층 부하에 대해 서버 추가만 하면 해결 가능, DB도 그럴까?

  1. 부 가 한 대 밖에 없는데 다운되었다면, 읽기 연산은 master로 전달된다. 또 즉시 새로운 slave가 장애를 대체한다. slave가 여럿이라면 다른 slave가 대체한다.
  2. master가 다운된다면, slave가 하나라면 그게 새로운 master가 된다. 모든 query는 master에서 수행된다. 그리고 새로운 slave가 추가된다. 프로덕션 환경에선 사실 더 복잡한데, slave에 보관된 데이터가 최신이 아닐 수 있다. 없는 데이터는 복구 스크립트를 돌려서 추가해야 한다. multi master나 원형 다중화를 도입하면 대처에 도움이 되지만, 책의 범위를 벗어난다.

        RDB의 다중화 vs newSQL

        - 다중 master의 경우, 비동기 update가 되면, 서로 충돌을 일으킬 수가 있다. *(write conflict) 이것을 해결하기 위한 여러 방법도 있긴 한데. 다른 얘기

        -cockRoachDB 같은 newSQL들이 있다. 모든 노드가 read, write를 수행하도록 한다. Raft 합의 프로토콜을 통해, 과반수 노드의 동의가 있어야 트랜잭션이 커밋된다. 물론, 동의받는 과정에서 시간지연이 발생하긴 한다. --- 

이제 웹계층(로드밸런서)과 DB(다중화)로 부하를 분산할 수 있게 되었다.

응답 시간의 경우, 캐시를 붙이고, 정적 콘텐츠를 CDN으로 옮겨 개선할 수 있다.

캐시

값비싼 연산결과, 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소다.

DB I/O가 비용이 비싸므로, 웹 서버 입장에서는 이것을 줄이는게 관건인데, 캐시는 이 문제를 완화할 수 있다.

캐시 계층

별도의 캐시 계층을 두면, 성능이 개선될 뿐만 아니라, 데이터베이스의 부하도 줄일 수 있고, 캐시 계층의 규모를 독립적으로 확장시키는 것도 가능하다.

캐시 전략의 대표적인걸로

읽기 주도형 캐시 전략(Read-Through Caching Strategy) 가 있다.

요청받은 웹서버는 캐시에 응답이 저장되어 있는지를 본다. 있으면 가져오고 없으면 DB가서 읽어 캐시에 쓴다.

데이터의 종류, 크기, 엑세스 패턴에 맞는 캐시전략들이 존재한다.

캐시 사용 시 유의할 점

CDN

CDN사용 시 고려해야 할 사항

Stateless 웹 계층

state 의존적인 아키텍처

stateless 아키텍처

데이터센터

메시지 큐

로그, 메트릭, 그리고 자동화

메시지 큐, 로그, 메트릭, 자동화 등을 반영하여 수정한 설계안

데이터베이스의 규모 확장

수직적 확장

수평적 확장

1M 사용자, 그 이상

results matching ""

    No results matching ""