본문 바로가기
Computer Science/서버 개발

[대용량 처리를 위한 MySQL 이해] 대용량 시스템의 이해

by sy.cho__ 2023. 4. 29.

이 글은 FastCampus에서 진행하는 "백엔드 개발자를 위한 한 번에 끝내는 대용량 데이터 & 트래픽 처리 초격차 패키지 Online" 강의를 공부하고 기록하기 위함입니다. 저작권 등이 문제가 생긴다면 바로 정리하도록 하겠습니다. 


초기 웹은 Client - 서버 - 데이터베이스를 나누어져 있었으나

요즘은 웹 서버- 웹 어플리케이션으로 나뉘어져 있는 경우가 많아요

웹서버는 HTML , Javascript가 주로 동작하고 웹 어플리케이션 서버는 데이터베이스와 통신하는 Java Spring, Node.js 등이 있죠

그럼 여기서 웹서버 - 웹어플리케이션 서버는 왜 나뉘어진 걸까요? 

웹서버의 복잡도가 점점 증가해서 그렇지만 주목적은 관심사의 분리 / 관측가능한 시스템 / 효율적인 리소스 사용이에요

관심사 또는 역할에 따라 모듈을 분리함으로서 역할에 맞는 다양한 최적화 기법과 이슈가 생겼을 때 처리해야 하는 범위를 좁힐 수 있어요. 

예를 들어 사용자에게 보여지는 화면에 새로운 기능을 추가하거나 수정이 필요할 때, 모든 소스가 합쳐져 있다면 전체 배포를 해야하거나 저거체 소스코드에 대한 변경점이 생길 수 있지만 분리가 되어 있다면 수정되는 부분만! 업데이트하고 배포해서 다른 소스엔 영향을 적게 줄 수 있죠. 

이렇게 관심사를 분리한 다음에 각 분리된 내용을 관측할 수 있도록! (모니터링이라구 하죠) 시스템을 만들면 어떤 부분에 이슈가 생겼는지 부하가 생겼는지 쉽게 파악하고 조치를 할 수 있을것 같아요. 또 이럴 경우 해당 부분에만 자원을 증설한다거나 소스 업데이트해서 효율적인 리소스 관리도 가능하구요

이렇게 서비스를 만들어서 사용자가 점점 많아진다면 어떻게 될까요? 좋은 서비스라면 내 주변 친구, 우리나라 사람뿐만 아니라 전세계의 사람들이 접근할 수 있을거에요.

이렇게 무제한적으로 늘어나는 사용자 수에 따라 서버의 응답속도는 점점 느려질 수 있어요. 가끔 연말이나 사용자가 몰리는 유명 공연 예약, 선착순 이벤트 같은 날이면 서버가 다운되거나 접속하는데까지 시간이 많이 필요할 때가 있죠. 

이를 해결하기 위해 서버를 늘려야 할텐데 여기서 스케일업 / 스케일 아웃 방법이 있어요

각 방법은 어떻게 다를까요? 

스케일업은 하나의 서버의 성능을 높이는 방법이에요. 가방에 물건을 담는다고 가정해보면 아주 큰 가방으로 바꾸는걸에요. 이와 달리 스케일 아웃은 작더라도 가방을 여러개 준비해놓는거죠. 

  스케일 업 스케일 아웃
유지보수 및 관리 쉬움 여러 서버에 적절히 분산하는 기술 필요
확장성 제약이 있음 자유롭게 늘릴 수 있음
서비스 업데이트 및 장애복구 서버가 1대므로 작업 중 서비스 다운 특정 서버가 작업중이더라도 다른 서버로 서비스 유지 가능

크게 두 방법의 차이를 보면 위 정리된 표와 같아요. 서비스에 따라 다르지만 하나의 서비스가 동작할 때 엄청 큰 자원을 필요로 한다면 스케일 업 방법이 필요할 수 있어요. 그렇지만 대용량 트랙픽의 경우엔 하나의 큰 서버보다 여러개의 서버로 나눠 서로 부하를 분산하는게 좋을 것 같아요. 

그리고 이렇게 여러 대 서버로 나누면 24시간 서비스 운영이 가능해요. 만약 사용자가 몰려 서비스에 이슈가 발생한다면? 작업 조치가 될 때까지 전국의 사용자는 서비스 이용을 못할거에요. 그렇지만 여러대의 서버 중 일부 서버에만 이슈가 생겼다면 조치하는 동안 다른 정상 동작하는 서버를 통해 사용자는 서비스를 이용할 수 있죠. 

그럼 이렇게 서버는 스케일 아웃 방법을 통해 부하분산을 할 수 있을것 같아요. 그럼 데이터베이스 어떨까요? 

데이터베이스는 데이터를 담고 있는 공간이에요. 만약 여러대의 데이터베이스로 나뉘어져있다면? 각 데이터베이스간 데이터를 동기화하는 추가 기술이 필요할거에요. 사용자가 매번 다른 데이터를 받으면 안되니까요. 그래서 데이터베이스를 스케일 아웃하려면 서버보다 더 많은 비용과 기술이 필요해요.

그리고 뿐만 아니라 데이터베이스는 데이터를 PC 디스크라는 공간에 저장을 하고 읽고 쓰고 있어요. 서버는 메모리에 저장하고 읽기 때문에 속도가 빠르지만 디스크를 읽는 데이터베이스는 상대적으로 느릴 수 밖에 없어요. 그리고 서버 <-> 데이터베이스 간 네트워크 통신에 따른 시간도 어느정도 소요될거구요. 

그래서 보통 사용자가 많아지고 트래픽이 많아지면 데이터베이스에서 많은 병목현상이 일어납니다. 이건 어떻게 하면 해결할 수 있을까요?


이런 많은 이슈를 해결하기 위해 우린 대용량 시스템을 설계해야 해요. 그런데 그게 쉽지가 않죠

대용량시스템이 어려운 이슈

1. 하나의 서버로 감당하기 힘들어 대부분 여러개의 서버 또는 데이터베이스를 사용해야 합니다.

2. 여러개의 서버에서 유입되는 데이터의 일관성을 보장할 수 있어야 합니다. 

3. 코드 한줄이 데이터에 미치는 영향범위가 굉장히 커집니다.

4. 여러 서비스들이 얽혀있어 시스템 복잡도가 상당히 높습니다. 

이렇게 어려움에도 불구하고 대용량 트랙픽을 처리하기 위해 우리는 시스템 구축을 해야하고 다음 3가지를 증명할 수 있어야 해요

고가용성 언제든 서비스를 이용할 수 있어야 해요
확장성 시스템이 비대해짐에 따라 증가하는 데이터와 트래픽에 대응할 수 있어야 해요
관측가능성 문제가 생겼을 때 빠르게 인지할 수 있어야하고 문제의 범위를 최소하할 수 있어야 해요

서비스가 점점 커짐에 따라 시스템이 어떻게 발전하는지 한번 확인해볼게요

초기 시스템이에요. 서버, 데이터베이스로만 이뤄져있지만 서비스 초창기엔 괜찮을 수 있어요. 그러나 사용자가 점점 많아지면 서비스가 느리다..! 라는 불만이 조금씩 나오겠죠

이를 해결하기 위해 서버를 스케일 아웃했어요. 로드 밸런서(Load Balancer)는 클라이언트의 요청이 여러대의 서버에 동일하게 분산할 수 있게 해주는 서비스에요. 만약 특정서버에만 작업이 몰리고 다른 서버는 놀고 있다면..? 서비스가 느려졌다는 문제를 해결하기 어렵겠죠? 대표적인 로드밸런서는 Nginx, HA Proxy등이 있어요. 이건 추가로 포스팅 하겠습니다. 

그러나 이렇게해도 어느순간 부터 사용자 불만이 다시 나올 수 있어요. 서버가 늘어난 만큼 동시에 데이터베이스에 요청하는 수가 많아질 것이고 데이터베이스 부하가 많아질거에요. 병목현상이 발생하게 됩니다. 

이를 해결하기 위해 "캐시" 서비스를 많이 사용하고 있어요. 캐시는 데이터베이스 부하를 최소화하는 것을 목표로 사용되는데 캐시에 먼저 데이터를 물어보고 있으면 바로 응답합니다. 만약 없다면 데이터베이스에 질의하고 이를 캐시에 갱신하구요. 이렇게 하면 자주 요청오는 같은 내용의 사용자 요청은 데이터베이스까지 도달하지 않기 때문에 많은 부하를 줄일 수 있을거에요. 대표적으로 Radis 같은 서비스가 있어요

많이 좋아지고 사용자 불만도 해결되었어요. 그러나 점점 서비스가 커지면서 다른 외부 서비스와 연동하는 일이 생길 수 있어요. 예를들어 서비스의 결과물을 메일로 보낸다거나? 카톡으로 전달할 수도 있죠. 저희 서비스에서 외부 서비스에 요청을 하고 이를 대기하는 동안 사용자의 불만은 점점 쌓일거에요. 

이렇게 외부서비스에 의존하는 Job은 비동기 큐로 분리할 수 있어요. 대표적은 RabbitMQ나 Kafka와 같은 서비스가 있어요. 비동기 큐는 간단히 말해서 작업을 요청하고 사용자는 다른 서비스를 이용합니다. 그러다 작업이 완료되면? 푸쉬알림 등으로 결과를 볼 수 있는거죠. 

이렇게 구성된 시스템이 많아지면 아래와 같이 전체적인 그림을 그릴 수 있어요

다음 포스팅엔 이번에 소개된 여러 기술 중 데이터베이스. MySQL에 대해 자세히 알아볼게요!

반응형