티스토리 뷰

1. 서버를 어떻게 확장시킬 것인가? - Scale Up VS Scale Out

만약에 내가 만든 이 서비스가 엄청 잘 돼서 사용자 수가 폭발적으로 늘어나고 이 많은 사람들이 동시에 접속한다면 서버

하나로 버틸 수 있을까? 아마 버틸 수 없을 것이다. 그럼 여기 저기서 나타나는 장애들로 인해 서비스 사용자들이 불편을

느낄 것이고, 아무도 나의 서비스를 사용하지 않겠지... 아무튼 이런 대참사(?)를 막기 위해서 대규모 트래픽을 감당할 수

있도록 서버의 성능을 향상시켜야 한다. 어떻게 하면 서버의 성능을 향상시킬 수 있을까?

Scalability

서버 아키텍처와 관련하여 구글링을 하다보면 서버의 Scalability가 중요하다고 한다.

Scalability is the property of a system to handle a growing amount of work by adding resources to the system.

<Scalability, From Wikipedia>

위키피디아에서는 Scalability를 시스템의 늘어나는 작업량을 자원을 추가하는 방법으로 처리하는 능력이라고 정의하고

있다. 시스템이 더 많은 작업을 처리하기 위해 이를 감당할 리소스를 추가하는 것도 하나의 Scalability라고 할 수 있는 것

이다. 예를 들어, 얼마나 많은 트래픽을 처리할 수 있는지, 스토리지 용량을 추가하기가 얼마나 쉬운지, 얼마나 많은

트랜잭션을 처리할 수 있는지 등 시스템 안에서도 많은 부분이 Scalability로 설명된다.

이러한 관점에서 시스템의 더 나은 성능을 위해 리소스를 확장하는 방법은 두 가지 방법이 있다.

 

  1. Scale Up
  2. Scale Out

 

- Scale Up

: Scale Up이란 서버의 사양을 높이는 것에 해당한다. 수직적 확장이라고도 불리며 하나의 기존 서버에 자원 (ex. CPU,

RAM, 메모리 등) 을 추가하거나 서버 자체를 고사양의 서버로 교체하여 서버의 성능을 향상시키는 것을 말한다. 즉, 서버

한 대의 성능만 높이는 것이다. 가령, 서버가 여러 대여도 서비스를 운영할 때 하나의 서버에서만 트래픽을 받는다면 이는

나머지 서버들이 함께 트래픽을 분담하기 위해 존재하는 것이 아니라 현재 운영 중인 서버에 장애가 발생할 때 이를 대체

하기 위한 스페어 역할로 존재하는 것이므로 Scale Out이 아닌 Scale Up이라고 할 수 있다.

- Scale Out

: Scale Out이란 서버의 수를 늘리는 것에 해당한다. 수평적 확장이라고도 불리며 기존 서버와 비슷한 사양의 새로운 서버

여러 대를 추가하여 서버를 재구성하는 것을 말한다. 즉, 서버를 병렬적으로 확장하는 것이라고 할 수 있다.

 

현재 나는 twitter, instagram과 같은 SNS 서비스를 구현하는 프로젝트를 진행 중이다. 이 두 가지 중 어떤 것이 더 이 프로

젝트와 적합한지 각각의 장단점을 비교하며 알아보자.

 

 

Scale Up

서버를 확장하기 가장 쉬운 방법은 수직적으로 확장하는 것이다. 서버 한 대에 상황에 맞게 부족한 장비를 추가하면 되기

때문이다. 그래서 자원의 변경에 따른 어플리케이션의 영향이 적은 편이다. Scale Up과 비슷한 사례를 일상생활에서 쉽게

찾을 수 있다. 바로 노트북이나 PC의 성능 업그레이드다. 시간이 지나면 노트북이나 PC의 성능이 떨어지기 마련이다. 이

럴 때 성능을 향상시키기 위해 메모리나 그래픽 카드 등 다양한 부품을 교체하거나 추가하기도 한다. 노트북을 업그레이

드 했다고 해서 노트북이 초기화되는 것이 아니기 때문에 우리가 노트북 환경을 재설정하거나 기존에 깔려있던 여러 프로

그램을 새로 까는 등 귀찮은 일을 하지 않아도 된다. 서버도 마찬가지다. 서버에 여러 장비를 추가하거나 교체해도 이로 인

한 관리 비용 및 운영 비용이 거의 발생하지 않고, 기존의 소프트웨어 라이센스를 그대로 이용할 수 있기 때문에 라이센스

를 새로 살 필요도 없다. 또한 한 대의 서버를 통해 모든 요청과 데이터가 처리되기 때문에 클라이언트의 상태정보를 저장

하여 stateful한 서비스를 구현하는데 수월하고 이에 대한 데이터 정합성이 보장된다.

 

그러나 고성능의 장비일수록 구매 비용이 만만치 않은데다가, 서버 한 대에 추가할 수 있는 장비의 수도 한정적이기 때문

에 성능 확장에 한계가 있다. 또한 어느 정도의 수준까지 오면 추가된 자원 대비 효과는 미미해진다. 그렇기 때문에 서버가

가진 최대한의 성능보다 큰 규모의 트래픽이 들어온다면 결국 버티지 못하고 부하가 발생한다는 처음의 문제에 맞닥뜨리

게 된다. Scale Up에 대한 또 다른 문제는 웹 브라우저에서 웹 서버로의 흐름의 SPOF(단일 실패지점)가 발생했을 때 해결

되지 않는다는 것이다. 예를 들면, 어플리케이션 사용자가 단시간 안에 급격하게 증가할 경우, 하나의 서버에 모든 트래픽

이 집중되어서 장애가 발생할 가능성이 높아진다. 그러나 해당 서버를 대체하여 서비스를 지원할 다른 서버가 없기 때문

에 시스템 전체의 중단으로 이어진다는 것이다.

 

그렇다면 이 Scale Up은 주로 어떤 상황에서 사용될까? Scale Up을 통해서 서버를 확장하면 모든 데이터 처리가 단일 서

버에서 이루어지므로 데이터가 자주 업데이트되어 데이터의 일관성이나 정합성의 보장이 필요한 환경에서 사용된다. 대

표적으로 데이터베이스 서버에 적합하다.

 

 

Scale Out

Scale Out은 기존 서버와 비슷한 사양 혹은 그보다 낮은 사양의 서버를 사용하기 때문에 Scale Up에 비해서는 비용이

저렴하다. 또한 필요에 따라 서버를 증설하고 제거하는 것이 용이하기 때문에 좀 더 유연한 확장이 가능하다.

서버가 여러 대라는 것에서 오는 이점은 또 있다. 여러 서버로 트래픽을 분산시킬 수 있어 장애 발생 가능성이 낮고 만약

서버 한 대에 장애가 생겨 운영할 수 없는 상황이 생겨도 나머지 서버들이 작업을 나눠서 처리 하면 되기 때문에 문제 없이

서비스를 제공할 수 있다. Scale Up과 달리 SPOF가 발생해도 대처가 가능하다는 것이다.

 

그러나 처음부터 애플리케이션을 분산 서버 환경에 맞게 설계한 경우가 아니라면 이를 구성하는 데에 시간적 비용이 발생

하며 이러한 환경을 잘 유지하고 관리하기 위해 전문적인 지식과 노하우가 절대적으로 필요하다. 분산 서버 환경을 위해

서는 로드 밸런싱, 데이터 파티셔닝, 데이터와 서비스에 대한 이중화 등의 다양한 지식을 가지고 있어야 하는데 특히 로드

밸런싱은 필수적이다. 로드 밸런싱에 대한 쉬운 예를 들어보자. 학창시절 체력 측정을 한 번쯤은 해본 경험이 있을 것이다.

그 중 어떤 검사는 안내해주는 종이 하나 없어 같은 검사를 하는 줄인데도 한 줄만 길게 늘어서서 기다리는 시간이 길어진

경우도 있다. 이럴 때면 지도하는 선생님이 검사를 빠르게 진행하기 위해 몰려있던 애들을 여러 곳에 분배해주셨다. 로드

밸런싱도 마찬가지다. 위와 같은 병목현상을 방지하기 위해 각 서버에 걸리는 부하를 균등하게 분산시키는 것이 로드 밸

런싱이다. 이 외에도 여러 서버들 간에 세션과 같은 상태정보를 어떻게 공유해야 할지에 관한 문제도 해결해야 한다.

(이는 다음 글에서 더 자세히 알아볼 예정이다.)

 

이러한 장단점을 가지고 있는 Scale Out은 비교적 단순하지만 많은 처리를 동시에 진행해야 상황에서 주로 사용된다.

또한, 여러 서버에서 동시에 데이터가 처리되기 때문에 데이터의 변화가 비교적 적게 일어나고 일어나더라도 정합성 유지

가 어렵지 않은 경우에 적절하다. 대표적으로 웹 서버에 적합하다.

 

 

두 방법 중 어떤 것이 더 적합할까?

지금까지 Scale Up과 Scale Out의 장단점 그리고 활용 예시도 살펴보았다. 그럼 이제 내가 진행하고 있는 프로젝트에는

어떤 방법이 더 적합할지 고민해보자. 현재 내가 진행하고 있는 프로젝트는 SNS 서비스를 제공하는 웹 어플리케이션 프

로젝트이다. 웹 서버에서는 많은 요청을 동시에 처리할 필요가 있지만 개개의 처리는 비교적 단순하다. 또한 SNS 서비스

특성 상 다른 서비스에 비해 데이터 정합성 이슈에 민감하지 않다.

 

예를 들어, 계좌 이체 서비스같은 경우, 어떤 사람이 다른 사람에게 돈을 이체했는데 아무리 짧은 시간동안이라도 상대방의 잔고는 그대로라면 이는 큰 문제로 이어진다. 그러나 SNS 서비스 같은 경우, 어떤 사람이 글을 하나 올렸는데 팔로워 화면에서 잠시 보이지 않더라도 서비스를 사용하는데 상대적으로 지장이 없다. 그러나 SNS 서비스는 장애가 발생하면 큰 타격을 입는다. 잠깐 접속이 되지 않아도 그 날 포털 사이트의 검색어 순위를 장악하는데 이러한 장애가 자주 일어나고 복구하는데도 시간이 걸린다면 이는 서비스 사용자의 감소로 이어질 것이다.

 

따라서, 첫 문단에 언급했던 "사용자 수가 폭발적으로 늘어나고 이 많은 사람들이 동시에 접속하는" 상황을 가정했을 때, 대규모 트래픽을 보다 잘 견뎌내고, 서버가 다운되어도 계속해서 서비스를 제공해줄 수 있는 Scale Out 확장 방법이 적절하다고 생각한다. 웹 서비스의 로그인을 구현할 때는 stateful한 서비스의 구현은 필수적이기 때문에 이를 구현하기 쉬운 Scale Up을 선택해야 되지 않나라고도 할 수 있지만 Scale Out을 선택해도 Sticky Session, 세션 클러스터링, 세션 스토리지 분리 등의 방식으로 해결할 수 있으므로 이는 충분히 커버가 가능하다.

 

 

그렇다면 이제 Scale Out을 선택했을 때 뒤따라오는 고민, 어떻게 여러 대의 서버에서 사용자의 세션 정보를 공유할 것인

가를 해결해야 한다. 왜냐하면 웹 서비스가 사용자에게 편리한 기능을 제공하는데에 세션 정보가 큰 역할을 하기 때문이

다. 다음 글에서는 이 문제를 정확히 파악하고 이를 해결할 다양한 방법에 대해서 알아볼 것이다.

 

 

 

  • 진행 프로젝트

https://github.com/f-lab-edu/sns-itda

 

f-lab-edu/sns-itda

Contribute to f-lab-edu/sns-itda development by creating an account on GitHub.

github.com

 

댓글