사전 오토스케일링
개념

오토스케일링

gabury1

오토스케일링은 부하에 맞춰 서버 대수를 자동으로 늘리고 줄입니다. 사람이 지표를 지켜보다 손으로 서버를 늘리는 대신, 미리 정해 둔 기준을 넘으면 시스템이 스스로 대수를 바꿉니다. 손님이 몰리는 동안에만 자원을 더 쓰고 한가해지면 도로 반납합니다.

쉽고 빠른 이해

오토스케일링은 부하를 보고 서버 대수를 알아서 바꾸는 장치입니다. 주문이 몰리는 저녁에는 서버를 넷으로 늘리고 새벽에는 하나로 줄이는 식입니다.

이게 없으면 제일 몰리는 때에 맞춰 서버를 늘 켜 두어야 합니다. 한가한 시간에도 같은 비용을 치르고, 예상보다 더 몰리면 사람이 손으로 늘릴 때까지 요청이 밀립니다.

어떻게 도나:

  1. 서버가 얼마나 바쁜지, 요청이 얼마나 밀렸는지를 주기마다 잽니다
  2. 그 값을 미리 정해 둔 기준과 견줍니다
  3. 기준을 넘으면 대수를 늘리고, 한참 밑돌면 줄입니다

대가는 반응이 늦다는 것입니다. 새 서버가 요청을 받을 준비를 마칠 때까지는 늘리기로 정해 놓고도 기존 서버들이 부하를 그대로 맞습니다.

상세

마트는 계산대를 여럿 두고도 평소에는 두 곳만 엽니다. 손님 줄이 길어지면 직원을 불러 계산대를 더 열고, 줄이 짧아지면 도로 닫습니다. 오토스케일링은 이 판단을 기계가 대신하는 것입니다.

줄을 보고 계산대를 여는 일을 사람이 맡으면 몰리는 때마다 누군가 지표를 지켜보고 있어야 합니다. 사람이 알아채고 손을 대기까지 요청은 계속 밀립니다. 새벽에 줄이는 것을 잊으면 아무도 안 쓰는 서버에 요금이 그대로 나갑니다. 오토스케일링은 이 두 가지를 기계에 넘깁니다.

오토스케일링은 부하를 나타내는 값을 주기마다 재고, 그 값이 기준을 넘으면 서버 대수를 늘리고 한참 밑돌면 줄이는 절차입니다. 부하를 나타내는 값이란 일이 얼마나 밀려 있는지를 알려 주는 숫자입니다. 서버가 얼마나 바쁜지를 보는 사용률, 처리되기를 기다리는 요청의 수가 그런 값입니다.

늘리고 줄이는 대상은 대개 서버 대수입니다. 같은 일을 하는 기계를 옆에 더 세우는 수평 확장을 기계가 알아서 하는 것입니다.

한 대의 크기를 키우는 수직 확장을 자동으로 하는 방식도 있습니다. 돌고 있는 기계의 프로세서나 메모리를 바꾸려면 대개 그 기계를 껐다 켜야 해서, 그동안 서비스가 끊깁니다.

사람이 앞날을 헤아려 자원을 미리 마련해 두는 용량 계획과는 반응하는 빠르기가 다릅니다. 용량 계획은 몇 주 뒤에 올 흐름을 미리 준비하고, 오토스케일링은 몇 분 사이의 변화에 답합니다. 둘은 서로를 대신하지 않고 같이 씁니다.

기준으로 삼는 값 두 갈래

기준으로 삼는 값은 크게 두 갈래입니다. 하나는 기계 쪽 값입니다. 프로세서가 쉬지 않고 일한 시간의 비율이나 메모리를 얼마나 썼는지처럼, 서버가 얼마나 바쁜지를 바로 보여 줍니다.

다른 하나는 일이 밀린 정도를 보여 주는 값입니다. 이 갈래에는 셋이 있습니다.

큐의 길이는 처리되기를 기다리는 요청이 몇 건인지 보여 줍니다. 초당 요청 수는 초당 몇 건이 들어오는지를 셉니다. 응답 시간은 요청 하나에 답하기까지 걸린 시간입니다.

어느 쪽을 쓸지는 무엇이 모자라서 느려지는지가 정합니다. 계산이 많은 서비스는 기계 쪽 값이 부하를 그대로 따라갑니다.

반대로 바깥 호출을 기다리느라 지연이 늘어나는 서비스는 서버가 한가해 보입니다. 그런데도 요청은 밀리므로 밀린 정도를 보는 값을 씁니다.

늘릴 때를 정하는 세 방식

무엇을 신호로 삼아 대수를 바꾸느냐로 방식이 갈립니다.

방식 언제 대수를 바꾸나 어디에 맞나
기준값 잰 값이 정해 둔 기준을 넘거나 밑돌 때 부하가 어떻게 움직일지 미리 모를 때
예약 정해 둔 시각이 되면 아침 아홉 시처럼 몰리는 때가 정해져 있을 때
예측 지난 기록으로 앞을 헤아려 미리 같은 모양이 되풀이될 때

기준값 방식이 바탕입니다. 다만 부하가 이미 오른 뒤에야 움직입니다. 나머지 둘은 그 늦음을 메우는 보완입니다.

오르는 때를 아는 서비스는 예약이나 예측으로 먼저 늘려 둡니다. 기준값 방식은 켜 둔 채로 둡니다. 미리 늘린 양이 모자라면 그때부터 기준값 방식이 더 늘립니다.

한 바퀴가 도는 순서

오토스케일링은 한 번 판단하고 끝나지 않고 같은 바퀴를 계속 돕니다.

flowchart TD
    A["부하를 나타내는 값을 잰다"] --> B["기준과 견준다"]
    B --> C["넘으면 늘리고 밑돌면 줄인다"]
    C --> D["바뀐 대수가 효과를 낼 때까지 기다린다"]
    D --> A

마지막 단계가 빠지면 이 바퀴는 헛돕니다. 대수를 바꾼 직후에 다시 재면 아직 효과가 안 나타난 값을 보고 또 바꾸게 됩니다.

한 번 움직인 뒤에는 정해진 시간 동안 판단을 쉽니다. 이 쉬는 시간을 쿨다운이라고 부릅니다.

늘린 서버가 요청을 받기까지

대수를 늘리기로 정한 순간 부하가 곧바로 나뉘지는 않습니다. 새 서버는 켜진 뒤 프로그램을 올립니다. 받을 준비가 됐는지 검사를 통과하면, 그제야 요청을 고르게 나눠 주는 로드 밸런서가 이 서버로 요청을 보냅니다.

sequenceDiagram
    participant 오토 as 오토스케일링
    participant 서버 as 새 서버
    participant 분배 as 로드 밸런서
    오토->>서버: 한 대 더 띄운다
    서버->>서버: 켜고 프로그램을 올린다
    분배->>서버: 받을 준비가 됐는지 검사한다
    서버-->>분배: 검사를 통과한다
    Note over 오토,분배: 여기까지 걸리는 동안 기존 서버들이 부하를 다 맞는다
    분배->>서버: 요청을 나눠 보낸다

준비가 됐는지 묻는 쪽은 로드 밸런서입니다. 새 서버가 스스로 합류하는 것이 아니라, 검사를 통과해야 요청을 받습니다.

이 준비 시간이 오토스케일링의 반응이 늦는 까닭입니다. 기준을 서버가 더는 못 버티는 지점에 바짝 붙여 두면 새 서버가 준비되기 전에 기존 서버들이 먼저 무너집니다. 기준은 아직 버틸 여유가 남아 있는 곳에 둡니다.

줄일 때 끊기는 요청

줄이는 쪽도 그냥 끄면 안 됩니다. 끄려는 서버가 처리하던 요청이 남아 있으면 그 요청들은 답을 못 받고 끊깁니다.

로드 밸런서에서 그 서버를 먼저 빼 새 요청이 안 가게 합니다. 들고 있던 요청을 다 끝낼 때까지 기다린 뒤에 끕니다.

sequenceDiagram
    participant 오토 as 오토스케일링
    participant 분배 as 로드 밸런서
    participant 서버 as 끄려는 서버
    오토->>분배: 이 서버로 새 요청을 보내지 마라
    분배--x서버: 새 요청이 더는 안 간다
    Note over 오토,서버: 들고 있던 요청을 다 끝낼 때까지 기다린다
    오토->>서버: 끈다

순서가 뒤집히면 이 절차가 소용없습니다. 먼저 끄고 나서 빼면 그 사이에 들어온 요청이 그대로 끊깁니다.

서버가 자기 안에 데이터를 들고 있으면 이 기다림만으로는 모자랍니다. 세션은 로그인한 사람이 누구인지를 서버가 기억해 두는 것입니다.

이 세션을 서버 메모리에 두면 그 서버가 꺼질 때 세션도 함께 사라집니다. 그 사용자는 로그인이 풀린 채로 다음 요청을 보냅니다.

오토스케일링을 쓰는 서비스는 그래서 서버가 요청 사이에 아무것도 안 들고 있게 만듭니다. 들고 있어야 하는 것은 서버 바깥에 따로 둔 저장소로 옮깁니다. 어느 서버가 꺼져도 그 저장소는 남아 있습니다. 이렇게 만든 서버를 무상태 서버라고 부릅니다.

늘렸다 줄였다를 되풀이하는 흔들림

기준을 하나만 두면 잰 값이 그 기준 언저리에서 조금씩 움직일 때마다 대수가 따라 흔들립니다. 늘리면 부하가 나뉘어 값이 내려가고, 값이 내려가면 줄이고, 줄이면 다시 올라갑니다. 서버는 켜지고 꺼지기를 되풀이하느라 정작 요청은 제대로 못 받습니다.

flowchart TD
    A["잰 값이 기준을 넘는다 · 기준은 하나뿐"] --> B["대수를 늘린다"]
    B --> C["부하가 나뉘어 값이 내려간다"]
    C --> D["대수를 줄인다"]
    D --> A

막는 방법은 둘입니다. 하나는 늘리는 기준과 줄이는 기준을 벌려 두는 것입니다. 늘릴 때의 기준보다 줄일 때의 기준을 훨씬 아래에 두면 그 사이에서는 아무 일도 안 일어납니다.

block-beta
columns 1
  a["늘리는 기준 위 · 대수를 늘린다"]
  b["두 기준 사이 · 아무 일도 안 일어난다"]
  c["줄이는 기준 아래 · 대수를 줄인다"]

가운데 띠가 위 고리를 끊는 곳입니다. 잰 값이 이 띠 안에서 움직이는 동안에는 늘리지도 줄이지도 않아 되먹임이 시작되지 않습니다.

다른 하나는 앞서 말한 쿨다운을 여기에도 쓰는 것입니다. 한 번 움직인 뒤 정해진 시간 동안 판단을 쉬면 값이 오르내려도 대수가 따라 움직이지 않습니다.

대수를 늘려도 안 풀리는 부하

대수를 늘려서 나아지려면 부하를 나눠 받을 수 있어야 합니다. 여러 서버가 데이터베이스 한 대를 함께 씁니다. 그 한 대가 이미 꽉 차 있으면 앞단 서버를 늘려도 기다리는 요청은 줄지 않습니다.

flowchart TD
    subgraph 앞단["앞단 서버"]
        S1["서버 1"]
        S2["서버 2"]
        S3["서버 3"]
    end
    S1 --> DB["데이터베이스 한 대 · 이미 꽉 찼다 · 병목"]
    S2 --> DB
    S3 --> DB
    NEW["늘린 서버"] -.-> DB

늘린 서버까지 같은 한 대로 내려갑니다. 앞단 서버는 한가해지지만 데이터베이스 앞에 요청이 그대로 쌓입니다. 밀리던 곳이 앞단 서버에서 데이터베이스로 옮겨 갔을 뿐입니다.

이렇게 전체를 가로막는 한 곳을 병목이라고 부릅니다. 오토스케일링은 병목을 옮길 뿐 없애지 못합니다.

부하가 순식간에 치솟는 경우도 어렵습니다. 새 서버가 준비되는 데 걸리는 시간보다 부하가 빨리 오르면 늘리는 판단이 늘 뒤늦습니다. 이런 서비스는 평소 대수를 여유 있게 두거나, 몰릴 때를 아는 만큼 예약으로 먼저 늘려 둡니다.

줄이는 기준이 정하는 요금

비용도 저절로 줄지 않습니다. 줄이는 기준을 헐겁게 잡으면 한가해져도 대수가 안 내려가 요금이 그대로 나갑니다. 빡빡하게 잡으면 흔들림과 요청 끊김이 늘어납니다.

기준을 어디에 둘지는 그 서비스가 지연을 얼마나 견디느냐가 정합니다. 답이 조금 늦어도 되는 서비스는 기준을 빡빡하게 잡아 요금을 아낍니다.

관련 항목

오토스케일링이 자동으로 수행하는 확장 방식

수평 확장 · 수직 확장 · 확장성 · 용량 계획

늘릴지 줄일지를 판단하는 근거 지표

사용률 · 처리량 · 초당 요청 수 · 응답 시간 · 꼬리 지연 · 오류율 · 골든 시그널

지표를 모아 기준 초과를 감시하는 장치

모니터링 · 메트릭 · 경보 · 관측성 · Prometheus · 대시보드

늘어난 서버에 요청을 나눠 주는 장비

로드 밸런서 · 부하 분산 · 리버스 프록시 · 라우팅 · 하트비트

오토스케일링이 올라타는 실행 환경

클라우드 · 가상화 · 가상 머신 · 컨테이너 이미지 · Kubernetes · 레플리카셋 · 디플로이먼트 · 파드 · 오케스트레이션

대수를 늘려도 안 풀리는 상태

병목 · 포화 · 데이터베이스 · 커넥션 풀 · 샤딩 · 복제

부하가 넘칠 때 대신 버티는 수단

스로틀링 · 백프레셔 · 서킷 브레이커 · 캐싱 · 우아한 저하 · 타임아웃

늘고 주는 서버가 지켜야 하는 성질

무상태 · 세션 · 고가용성 · 가용성 · 헬스 체크

늘리기 전에 한계를 재 두는 수단

부하 테스트 · 벤치마크 · 가상 사용자 · 스트레스 테스트

다른 이름: autoscaling · auto scaling · 자동 스케일링