개발

대규모 서비스를 지탱하는 기술 1장

p829911 2022. 3. 16. 17:56

대용량 서비스?

서비스의 규모는 서버 대수 등으로 개략적으로 파악되는 경우가 많은데, 이런 관점에서 볼 때 백 대에서 수천 대 정도가 대규모 서비스라고 할 수 있다.
구글과 페이스북의 서버 대수는 수백만 대 규모이고, 처리하는 데이터는 테라바이트 ~ 페타바이트 급의 초대규모 서비스이다.

소규모 서비스와 대규모 서비스의 차이

확장성 확보, 부하분산 필요

Scale-out: 서버를 횡으로 전개, 즉 서버의 역할을 분담하거나 대수를 늘림으로써 시스템의 전체적인 처리능력을 높여서 부하를 분산하는 방법이다. 반면 Scale-up은 하드웨어의 성능을 높여 처리능력을 끌어올리는 방법이다. (하드웨어의 성능과 가격은 비례하지 않는다)
저가의 하드웨어를 횡으로 나열해서 확장성을 확보하는 것이 스케일 아웃 전략이다. 스케일 아웃 전략을 채용한 경우 비용이 절감되지만 다양한 문제가 발생한다.

Scale-out 전략을 채용할 때 나타날 수 있는 문제점

  • 사용자로부터의 요청을 어떻게 분배할 것인가?  → 로드밸런서
  • 데이터 동기화는 어떻게 할 것인가?
    DB를 분산시켰을 때 한쪽에 저장된 갱신 내용을 다른 한쪽 DB가 알지 못한다면?
  • 네트워크 통신의 지연시간을 어떻게 생각해볼 수 있을까? 작은 데이터라도 이더넷(Ethernet)을 경유해서 통신할 경우 ms 단위의 지연시간이 있다.

다중성 확보

시스템은 다중성을 지닌 구성, 즉 특정 서버가 고장 나거나 성능이 저하되더라도 서비스를 계속할 수 있는 구성으로 할 필요가 있다.

스케일 아웃을 해서 서버 대수가 늘어나면 서버의 고장률도 필연적으로 올라가게 된다. 그러므로 어딘가 잘못되면 서비스가 전부 정지해버리는 설계는 24시간 365일 계속 가동되어야 하는 웹 서비스에는 용납할 수 없다. 서버가 고장나더라도 혹은 급격하게 부하가 올라갈 경우에도 견딜 수 있는 시스템을 구성할 필요가 있다.

 

효율적 운영 필요

서버가 100대가 넘어가면 어떤 서버가 무슨 역할을 하고 있는지 기억할 수 없다. 또한 각 서버가 어떤 상황에 있는지 파악하기도 힘들다. 당연히 감시용 소프트웨어를 사용하고 정보관리를 위한 툴을 사용하는 등 자동화를 하게된다. 그러나 이 시스템을 구축하거나 시스템을 통해 정보를 보는 것도 결국 인간이다. 일손을 거치지 않고 대규모 시스템을 건강한 상태로 얼마나 계속 유지할 수 있을까?

 

개발자 수, 개발 방법의 변화

대규모 서비스가 되면 당연히 혼자서는 개발이나 운용할 수 없다. 여러 기술자가 역할을 분담하게 되는데 여기서 개발 표준화가 중요하다. 애플리케이션을 각각의 기술자가 각각의 방식대로 개발하게 된다면 생산성이 오르지 않는다. 프로그래밍 언어를 통일하고, 라이브러리나 프레임워크를 통일하고, 코딩 규약을 정해서 표준화하고 소스코드 관리를 버전관리 시스템으로 제대로 해야 여러 사람이 작업할 때 좋은 효율이 나타난다.

대규모 데이터량에 대한 대처

컴퓨터는 디스크(HDD)에서 데이터를 로드해서 메모리에 저장, 메모리에 저장된 데이터를 CPU가 패치(fetch) 해서 특정 처리를 수행한다. 또한 메모리에서 패치된 명령은 보다 빠른 캐시(cache) 메모리에 캐싱된다. 이처럼 데이터는 디스크 → 메모리 → 캐시메모리 → CPU와 같이 몇 단계를 경유해서 처리되어 간다. 각 단계 간에는 속도차가 매우 크게 나는데 이 속도차를 흡수하기 위해 OS는 이런저런 방법을 사용하게 되는데, 예를 들면 디스크로부터 읽어들인 데이터를 메모리에 캐싱해둠으로써 전반적으로 디바이스간 속도차가 체감속도에 영향을 주지 않도록 하고 있다. DB를 비롯한 미들웨어도 기본적으로 이러한 속도차를 의식한 데이터 구조, 구현을 채용하고 있다.

하지만 OS나 미들웨어 등의 소프트웨어에서 이런 구조를 통해 분발한다고는 해도 당연히 한계는 있다. 데이터량이 많아지면 처음부터 캐시 미스(cache miss)가 많이 발생하게 되고, 그 결과로 저속의 디스크로의 I/O가 많이 발생하게 된다. 디스크 I/O 대기에 들어선 프로그램은 다른 리소스가 비어 있더라도 읽기가 완료되기까지는 다음 처리를 수행할 수가 없다. 이것이 시스템 전체의 속도저하를 초래한다.

해결 과제

어떻게 하면 데이터를 적게 가져갈 수 있을까?, 여러 서버로 분산시킬 수 있을까?, 필요한 데이터를 최소한의 횟수로 읽어들일 수 있을까?