티스토리 뷰

반응형

가상 면접 사례로 배우는 대규모 시스템 설계 기초 북리뷰 1장을 시작하겠습니다. 먼저 천리길도 한 걸음부터라는 말이 있듯이 복잡한 시스템을 설명하기 전에 가장 단순한 서버부터 설명하고자 합니다. 

먼저 단일 웹서버와 데이터베이스로 시작을 해보겠습니다. 사용자가 사용자 단말 웹브라우저 또는 클라이언트 앱을 이용하여 특정 도메인의 데이터를 요청하면 DNS는 해당 도메인을 ip로 resolve하고, 해당 웹서버로 요청을 가게끔 해줍니다. 그림은 아래와같습니다.

클라이언트의 요청을 받은 웹서버는 필요에 의해 데이터베이스에 접근하여 데이터를 가져오거나 쓰게됩니다. 그리고 데이터를 반환하거나 쓰기 결과를 반환할 수 있습니다. 지금 껏 본 것이 단일 서버, 단일 데이터베이스의 구조입니다.

잠시 다중 웹서버로 넘어가기 전, 어떤 데이터베이스를 쓸지 고민하는 단계에 대해 설명 드리겠습니다. 전통적으로 RDBMS를 쓸 수 있습니다. 다만 대용량 데이터를 다루거나 비정형 데이터를 다룰때, 또는 낮은 응답 지연시간이 요구 될 때 NoSQL을 고려할 수도 있습니다. RDBS는 특징으로 정규화와 조인이 있는데, 해당 조인 연산이 고비용 연산으로 어려운 경우가 있습니다. 예로, RDBMS에서는 30억건 * 30억건 조인을 하는 경우가 있을 듯 합니다. 이런 경우 등, NoSQL도 고려해볼 수 있을 듯 합니다. 

이제, 다중 웹 서버로의 내용으로 넘어가보겠습니다. 다중 웹서버는 수평적 규모 확장에 해당합니다. 스케일 아웃이라고도 표현합니다. 수직적 규모 확장은 한대의 웹서버의 자원(CPU, RAM)을 증가시키는 데 이는 반드시 다음과 같은 문제를 담고 있습니다. CPU, RAM을 머신 한 대에 무한 대로 증설할 수도 없을 뿐더러, 증가할 때마다 비용은 점점 더 올라 갈 것입니다. 그리고 서버에 장애가 발생하면 클라이언트의 동작은 완전히 중단 될 것 입니다. 그래서 대규모 애플리케이션을 지원하는 데에는 다중 웹 서버의 설계는 필요하다고 할 수 있습니다.

로드밸런서는 부하 분산 집합에 속한 웹 서버들로의 트래픽 부하를 고르게 분산하는 역할을 합니다. 로드밸런서는 public ip를 통해 접근 된 요청은 내부 private ip address로 변환되어 특정 서버로 전송합니다. 브라우저와 앱에서 요청된 HTTP는 로드밸런서에 의해 적절한 서버로 요청을 전달합니다. 대표적으로 NGINX, k8s의 Ingress-NGINX 를 떠올리면 될 듯 합니다. 만약 특정 서버가 다운되면 트래픽은 적절하게 사용 가능한 다른 웹 서버로 전달 됩니다.
 또한, 유입되는 트래픽이 가파르게 증가하면 n 대의 서버로 트래픽을 처리할 수 없는 경우가 있습니다. 웹 서버 계층에 서버만 추가하면, 로드밸런서는 이를 우아하게 처리할 수 있습니다. 자동적으로 트래픽을 분산하기 시작할 것 입니다.
 이로써 웹 서버 다중화는 로드밸런서의 도움으로 이루어 질 수 있습니다.

데이터베이스 다중화는 어떻게 처리할 수 있을까요? 웹 서버 와 마찬가지로 데이터베이스도 수직적 규모확장도 좋은 선택이지만 언젠가는 수평적 규모확장을 택해야할 때가 올 것 입니다. DBMS에서는 기본적으로 다중화를 지원합니다. 예전 용어로 주-부 데이터베이스(master-slave)로 부르기도 하였습니다. 요새는 head-worker로 부릅니다. head db는 쓰기 전용으로, worker db는 읽기 전용입니다. RDBMS의 경우 쓰는 경우 B+ 인덱스의 정렬이 필요하므로 연산속도가 느리지만 대부분의 애플리케이션에서는 읽기가 많이 일어납니다. n대의 worker db에서 읽는 연산이 분산되므로 데이터베이스 다중화의 이점이 있습니다. 또한 자연 재해등 의 이유로 DB 서버 가운데에 일부가 파괴되어도 데이터는 보존될 수 있습니다. 데이터를 여러 지역에 복제해두어, DB 서버하나에 장애가 생기더라도 계속 서비스 할 수 있게끔 할 수도 있습니다.

DB도 로드밸런서를 둔 것 처럼, head DB가 다운시 worker DB가 head DB로 승격하여 운영 가능합니다. 단, head DB와 worker DB가 동기화가 되어 있지 않은 경우도 있습니다. 이 경우 복구 스크립트를 호출하여 head DB의 데이터를 worker DB에 복사하거나, 다중 head DB, 원형 다중화를 이용하여 대처할 수 있습니다.

캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤 이은 요청이 보다 빨리 처리될 수 있는 저장소를 뜻 합니다. CPU의 캐시와 같습니다. 이 경우 HTTP 요청에 대해 데이터베이스의 접근 없이 캐시 DB가 저장하여 해당 값을 보여주는 경우 입니다. 캐시 계층을 두면 DB의 부하가 줄어듭니다. 

다만 캐시 사용시 주의할 점은 다음과 같습니다. 데이터 갱신이 자주 일어나지 않지만 참조가 많을 때 사용 해볼 것, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직 하지 않습니다. 만료된 데이터를 판별하는 기준도 있어야합니다. 만료된 경우 적절하게 DB에 접근하여 새로운 데이터를 가져와야합니다. DB와 캐시의 값이 같은 것을 일관성이라고 하는데, 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랙잭션으로 처리되지 않은 경우 일관성이 깨질 수 있습니다. 캐시의 장애 중 가장 크리티컬한것은 SPOF 입니다. 캐시 서버도 또한 분산해야합니다. 캐시메모리를 적절하게 잡아 잦은 eviction, 또는 너무 크게 잡아 overprovistion 하지 않도록 유의해야합니다. 

콘텐츠 전송 네트워크 CDN은 아래 설명으로 넘어갑니다. CDN은 대개 제 3 제공자에 의해 됩니다. 다만 NGINX를 이용하여 내부 CDN을 둘 수도 있을 것 입니다.

웹 계층은 무상태로 두어야 수평적 확장이 쉽습니다. 유상태로 하게 된다면 중간 로드밸런서가 특정한 클라이언트의 요청이 해당 상태를 가지고 있는 서버로 HTTP 요청을 전달해야하는 sticky session 기술을 사용해야할 것 입니다.

데이터 센터는 지리적 라우팅을 이용하여 장애에 대응 하는 방식입니다. 해당 데이터센터가 죽은 경우 로드밸런서에 의해 다른 데이터센터로 이동할 수 있습니다. 데이터센터는 다음과 같은 기술적 난제를 가지고 있습니다. 올바른 데이터 센터로 트래픽을 보내는 효과적 방법을 찾아야합니다. 예로 GeoDNS는 사용자에게서 가장 가까운 데이터센터로 트래픽을 보낼 수 있습니다. 데이터 센터별로 별도의 데이터베이스를 사용하고 있으므로, 장애가 자동으로 복구되어 트래픽이 다른 데이터베이스로 우회한다고 해도, 해당 데이터센터에 그 데이터가 있음을 보장해야합니다. 이를 데이터 동기화 문제라고 합니다. 마지막으로, 자동화 배포도구는 어떤 데이터센터에도 동일한 서비스가 설치되어 웹사이트와 애플리케이션 여러 군데에서 테스트 할 수 있어야 합니다. 

메시지 큐의 역할은 생산자와 소비자를 디커플링하는데에 있습니다. 메시지 큐의 특징은 누군가 소비 하지 않으면 그대로 그 메시지가 유지하는데에 잇습니다. 그래서 작업 큐가 많이 밀렸을때 소비자를 능동적으로 증가 시킬 수 있고, 작업 큐가 덜 쌓여 있을 때엔 소비자를 능동적으로 줄일 수 있어야 합니다. 

로그, 메트릭 그리고 자동화는 당장 필요없을지라도, 사업규모가 커지고 나면 필수적으로 투자해야합니다. 로그는 에러 로그를 모니터링 하는데에 중점을 둡니다. 시스템의 오류와 문제들을 찾아 낼 수 있 어야합니다. 예로 ELK가 있을 듯 하네요. 그리고 메트릭은, 시스템의 현재 상태를 손쉽게 파악하는데 중점이 있습니다. 메트릭의 대표적인 Tool로는 grafana가 있습니다. 메트릭의 단위로는 호스트 단위 메트릭(CPU, 메모리), 종합 메트릭(DB 계층 성능, 캐시 계층 성능), 핵심 비즈니스 메트릭(일별 능동 사용자, 수익, 재방문) 등이 있습니다. 그리고 자동화는 개발 생산성을 유지하기 위해 반드시 필요한 것 입니다. 테스트 자동화, 빌드 자동화, 배포 등의 절차가 자동화가 되면 개발 생산성을 크게 향상시킬수도 있습니다.

아래는 최종적인 대규모 아키텍처의 예입니다.

 

데이터베이스의 규모확장에 대해 조금 더 세밀하게 보자면, 먼저 수직적 확장도 그리 나쁜선택은 아닙니다. 스택오버플로를 예로 들면 천만명 사용자 전부를 단 한대의 마스터 데이터베이스로 처리하였다고 합니다. 다만, 수평적 확장을 사용해야할 때가 오는데 이 때 샤딩 전략을 통해 다중 데이터베이스 구조에서 적절한 데이터베이스로 데이터를 저장하는 방식을 사용할 수 있습니다. 샤딩에 대한 문제는 재샤딩, 유명인사문제, 조인과 비정규화 가 있습니다. 

 

반응형