수평 확장

Horizontal Scaling

방법

같은 사양의 서버 대수를 늘려 늘어난 요청을 여러 대가 나눠 받게 만드는 확장 방식입니다.

등장 배경

서비스가 느려지기 시작할 때 오래도록 답은 하나였습니다. 쓰던 기계를 더 좋은 기계로 갈아 끼우는 것입니다. 메모리를 8기가에서 32기가로 올리면 한 대가 받아 내는 요청이 늘었고, 프로그램은 한 줄도 고치지 않아도 되니 가장 손쉬운 수였습니다.

이 방식은 두 군데서 막힙니다. 하나는 천장입니다. 한 대에 꽂을 수 있는 메모리와 프로세서에는 팔 수 있는 최대치가 있어서, 그 사양에 닿고 나면 돈을 더 내도 살 것이 없습니다. 다른 하나는 그 한 대가 멈추는 순간입니다. 아무리 비싼 기계라도 디스크가 고장 나면 서비스 전체가 같이 내려가고, 열 배 비싼 기계를 샀다고 고장이 열 배 덜 나지는 않습니다.

페이지덱이 회원가입 이벤트를 돌린 날 이 두 가지가 한꺼번에 나왔습니다. 평소의 여섯 배가 몰려 문서 편집 화면이 15초씩 멈췄고, 태오가 사양을 올리려고 보니 이미 그 사업자가 파는 가장 큰 사양이었습니다. 살 것이 없어서 못 사는 상황이었습니다.

수평 확장은 이 막다른 길에서 방향을 바꾼 답입니다. 한 대를 크게 키우는 대신 같은 크기의 기계를 여러 대 두고 요청을 나눠 받게 합니다. 대수는 계속 늘릴 수 있으니 천장이 사라지고, 한 대가 죽어도 남은 대수가 받아 주니 서비스가 통째로 멈추지 않습니다.

사용 절차

프로그램을 어느 대가 받아도 같은 답을 내게 고치는 일부터 시작해, 서버를 여러 대 띄우고 그 앞에 요청을 나눠 보내는 장치를 세우는 순서로 진행합니다. 네 단계입니다.

  1. 서버가 사용자별 정보를 자기 안에 쌓아 두지 않게 고칩니다. 로그인한 사람이 누구인지를 1번 서버의 메모리에만 적어 두면, 다음 요청이 3번 서버로 가는 순간 그 사람은 로그아웃된 것처럼 보입니다. 이렇게 요청 사이의 정보를 서버가 들고 있지 않는 설계를 무상태라고 하고, 그 정보는 서버 밖 공용 저장소로 옮깁니다.
  2. 여러 대가 정확히 같은 프로그램을 돌리게 만듭니다. 손으로 설치하면 1번 서버와 5번 서버에 다른 버전이 올라가 특정 사용자에게만 오류가 납니다. 실행에 필요한 것을 통째로 묶어 어디서나 같게 돌게 만든 단위인 컨테이너로 찍어 내면 이 차이가 없어집니다.
  3. 서버들 앞에 로드 밸런서를 세웁니다. 들어온 요청을 뒤에 선 여러 대 중 한 곳으로 넘기는 장치입니다. 주기적으로 각 서버에 신호를 보내 대답이 없는 대는 명단에서 빼기 때문에, 한 대가 죽어도 사용자는 모르고 지나갑니다.
  4. 몇 대를 띄워 둘지 정합니다. 고정 대수로 두거나, 부하에 따라 자동으로 늘리고 줄이는 오토스케일링에 맡깁니다. 후자는 새벽에 2대로 줄고 점심에 8대로 느는 식이라 노는 기계에 내는 돈도 줄어듭니다.

여기까지 해도 저장소는 여전히 한 곳입니다. 서버를 10대로 늘려도 모두 같은 데이터베이스 한 대를 두드리면 그 한 대가 새 병목이 됩니다. 읽기가 많으면 같은 데이터를 여러 대에 복사해 두는 복제로 나누고, 데이터가 너무 크면 조각내 여러 대에 나눠 담는 샤딩까지 갑니다.

적합한 상황과 한계

요청이 서로 독립적이고 어느 대가 처리해도 결과가 같은 일에 잘 맞습니다. 웹 페이지를 그려 보내거나 이미지 크기를 줄이는 일이 그렇습니다. 요청 100만 건을 10대에 10만 건씩 나눠 줘도 결과가 달라지지 않기 때문입니다. 반대로 한 덩어리로만 풀 수 있는 긴 순차 계산은 열 대에 나눠 준다고 10분의 1로 줄지 않습니다.

한계는 세 가지입니다.

  1. 늘린 만큼 빨라지지 않습니다. 2대를 4대로 늘리면 처리량이 두 배가 될 것 같지만, 공용 저장소를 기다리는 시간이 붙어 실제로는 1.7배쯤에서 멈춥니다.
  2. 운영할 것이 대수만큼 늘어납니다. 서버 한 대를 보던 팀이 20대의 로그를 뒤져 오류가 어느 대에서 났는지부터 찾아야 합니다. 로그를 한곳에 모으는 장치를 함께 갖추지 않으면 장애 시간이 오히려 길어집니다.
  3. 준비에 시간이 듭니다. 사용자별 정보를 서버 밖으로 빼내는 작업은 코드를 고치는 일이라 몇 주가 걸리기도 합니다. 오늘 밤 트래픽을 넘겨야 한다면 사양을 올리는 쪽이 현실적입니다.

그래서 두 방식은 대개 같이 씁니다. 급한 불은 사양을 올려 끄고, 그 사이에 대수를 늘릴 수 있는 구조로 옮깁니다.

실무 용례

"이번 프로모션은 수평 확장으로 버팁니다. 미리 6대까지 올려 두죠."

행사 시작 전에 서버 대수를 늘려 두겠다는 뜻입니다.

"이 기능은 아직 수평 확장이 안 돼요. 세션을 서버 메모리에 들고 있어서요."

대수를 늘리면 로그인이 풀리는 상태라 먼저 고칠 곳이 있다는 말입니다.

"대수를 두 배로 올렸는데 응답 시간이 반으로 안 줄었어요. 디비 쪽을 봐야 할 것 같습니다."

서버가 아니라 저장소가 병목이라는 진단입니다.

페이지덱이 대기업 고객사와 계약한 뒤 태오가 두 달에 걸쳐 밟은 순서가 그대로 이 절차였습니다. 로그인 정보를 서버 메모리에서 공용 저장소로 옮기고, 서버를 3대로 늘려 앞에 요청을 나눠 보내는 장치를 뒀습니다. 평일 오전 10시의 응답 시간이 2.4초에서 0.9초로 떨어졌습니다.

효과는 속도만이 아니었습니다. 한 달 뒤 서버 한 대에서 디스크 오류가 났는데, 예전 같으면 40분 멈췄을 일이 사용자 눈에는 아무 일도 아닌 채로 지나갔습니다. 수아가 고객사에 장애 공지를 쓸 일이 없어졌습니다.

흔한 오해

대수를 늘리면 성능이 그만큼 늘어난다고 생각하기 쉽습니다. 2대에서 4대로 가면 두 배일 것 같고, 대수와 처리량이 같은 방향으로 움직이니 자연스러운 계산입니다. 하지만 요청 하나를 처리하는 데 서버 밖의 공용 저장소를 한 번씩 들러야 하고, 그 저장소는 대수를 늘려도 그대로입니다. 4대로 가면 1.7배, 10대로 가면 3배쯤에서 멈추는 일이 흔합니다. 이걸 모르고 대수만 계속 늘리면 요금은 다섯 배로 내면서 속도는 세 배만 얻습니다.

수평 확장이 장애를 없애 준다는 오해도 잦습니다. 한 대가 죽어도 서비스가 도는 장면을 보면 그렇게 읽히기 쉽습니다. 실제로는 남은 대수가 죽은 대의 몫까지 받아 내는 구조라, 4대로 겨우 버티던 서비스에서 한 대가 빠지면 남은 3대가 순서대로 넘어지기도 합니다. 한 대가 빠져도 감당되게 여유를 두고 대수를 정해야 값을 합니다.

자주 헷갈리는 용어

용어무엇을 키우는가수평 확장과의 차이
수직 확장서버 한 대의 사양코드를 안 고쳐도 되어 빠르지만 살 수 있는 사양에 천장이 있고 바꾸는 동안 그 한 대가 멈춥니다
확장성키울 수 있는 성질 자체수평 확장은 그 성질을 얻는 방법 하나입니다. 확장성은 목표고 수평 확장은 수단입니다

같이 보면 좋은 페이지

  • 인프라

    서버를 늘린다는 말이 어느 판 위에서 벌어지는 일인지 봅니다

  • 수직 확장

    같은 문제를 반대 방향으로 푸는 수이고, 실무에서는 둘을 같이 씁니다

마지막 업데이트 2026-09-16