오토스케일링, 늘리는 것보다 줄이는 것이 어렵다
부하가 줄었다고 실행 중인 일을 바로 멈출 수는 없어요. 자동 확장이 판단하는 시점과, 늘리고 줄일 때 서로 다른 위험을 알아봐요.
이 글의 목차목표를 정하고 따라가게 하기4
식당 홀에 직원을 몇 명 둘지는 손님 수를 보고 정해요. 손님이 늘면 더 부르고 빠지면 퇴근시켜요. 그런데 퇴근시키는 쪽이 까다로워요. 계산을 받고 있는 직원을 그 자리에서 보낼 수는 없고, 손님이 빠졌다고 판단한 근거가 십 분 전 상황일 수도 있어요.
ECS 서비스에는 유지할 태스크 개수를 지정해요. 이 글은 그 숫자를 자동으로 바꾸는 이야기이고, 사고는 거의 언제나 줄이는 쪽에서 나요.
목표를 정하고 따라가게 하기
가장 널리 쓰이는 방식은 지표 하나를 정해 두고 그것을 목표값에 맞추게 하는 것이에요. AWS 문서는 이 방식을 지정한 지표를 목표값으로 유지하도록 개수를 조정하는 정책으로 설명해요. 사용률이 목표보다 높으면 늘리고 낮으면 줄여요.
원리는 온도 조절기와 같아요. 그래서 온도 조절기가 갖는 문제도 함께 와요. 난방을 켜도 방이 데워지기까지 시간이 걸리고, 그동안 온도계는 여전히 낮은 값을 보여 줘요. 그 값만 보고 계속 더 켜면 나중에는 너무 더워져요. 이 되먹임 구조에서 지연은 부수적인 문제가 아니라 설계의 중심이에요.
줄일 때 무엇이 죽나
늘릴 때는 기존 대상이 계속 일할 수 있어요. 그래도 늘어나는 속도보다 요청이 빨리 쌓이면 시간 초과나 요청 거절이 생길 수 있어요. 새 대상들이 동시에 데이터베이스 연결을 맺거나 캐시를 채우면서 뒤쪽 부하를 키울 수도 있고요. 늘리기는 언제나 안전하다고 단정할 수는 없어요.
줄이는 쪽은 달라요. 줄인다는 것은 도는 것을 죽인다는 뜻이고, 죽이는 대상은 지금 무언가를 처리하고 있을 수 있어요. 앞 글에서 다룬 등록 해제 대기가 여기서 다시 나와요. 새 요청을 보내지 않고 진행 중인 연결이 끝나기를 기다리는 시간과, 앱이 종료 신호를 받고 마무리할 시간이 필요해요. 작업이 이 시간을 넘기거나 앱이 신호를 처리하지 못하면 응답이 끊길 수 있어요.
같은 작업이 남아 있는 서버를 두 방식으로 종료해 보세요.
기존 서버
작업 처리 중아직 응답하지 않음
종료 결정
서버 한 대 줄이기기존 작업
중간에 끊김기존 서버
종료됨기존 작업
응답 완료기존 서버
그 뒤 종료작업을 처리하던 서버를 바로 끊으면 응답이 사라져요. 새 요청을 막고 기존 작업을 기다리는 시간이 따로 필요해요.
개수는 줄일 수 있지만 이 서버의 작업은 아직 끝나지 않았어요.
같은 출발점의 두 선택을 비교해요. 작업이 대기 시간 안에 끝나고 앱이 종료 신호를 처리한다고 가정하며, 실제 지연이나 scaling cooldown을 재지 않아요.
쿨다운은 작업을 마무리하는 대기 시간과 다른 값이에요. 개수를 바꾼 뒤 다음 조정을 얼마나 기다릴지 정해요. 문서는 확대 쪽과 축소 쪽의 의도를 다르게 적어 둬요. 확대는 지나치지 않게 이어서 늘리는 것이고, 축소는 가용성을 지키려고 보수적으로 줄이는 것이에요.
우선순위도 함께 적혀 있어요. 축소 쿨다운이 도는 중에 확대가 필요해지면 그 쿨다운은 중단되고 즉시 늘어나요. 줄이던 중이라도 늘려야 할 때는 늘리는 쪽이 이긴다는 뜻이에요.
지표는 항상 조금 늦다
판단 근거가 아예 없어지는 경우도 있어요. 지표에 데이터가 비면 알람이 판단 불가 상태로 넘어가고, 그동안에는 새 데이터가 들어올 때까지 조정 자체가 이뤄지지 않아요. 앞 글에서 다룬 알람의 세 번째 상태가 여기서 대수를 붙들어 둬요.
세 번째 문제는 판단 근거 자체에 있어요. 지표는 일정 간격으로 모이고, 모인 뒤에 평가되고, 평가된 뒤에 조정이 시작되며, 조정한 것이 실제로 일하기까지 또 시간이 들어요. 이 지연을 다 합치면 결정은 언제나 과거의 상황을 보고 내려져요.
지연이 길수록 두 가지 실패가 생겨요. 갑자기 몰리는 트래픽에는 늦게 반응해서 늘어나기 전에 이미 밀리고, 목표를 지나치게 민감하게 잡으면 늘렸다 줄였다를 반복하며 진동해요. 그래서 이 값들을 고를 때는 지표 하나만 보는 것이 아니라 한 번 조정한 결과가 지표에 나타나기까지 얼마나 걸리는지를 함께 재야 해요.
| 방향 | 늦으면 | 성급하면 |
|---|---|---|
| 늘리기 | 몰린 뒤에 늘어나 이미 밀린다 | 잠깐의 튐에도 자원이 늘어난다 |
| 줄이기 | 필요 없는 자원이 계속 돈다 | 처리 중인 요청이 끊긴다 |
| 지표 간격 | 반응이 통째로 밀린다 | 잡음에 흔들려 진동한다 |
확대가 늦어도 요청은 실패할 수 있고, 축소가 성급해도 실패할 수 있어요. 차이는 실패하는 과정이에요. 앞은 필요한 용량이 오기 전에 밀리고, 뒤는 이미 처리하던 일을 끊을 수 있어요. 그래서 늘릴 때의 준비 시간과 줄일 때의 마무리 시간을 따로 생각하는 편이 좋아요.
저는 왜 자동으로 두지 않았나
제가 만드는 앱의 AI 응답 서버에는 이 장치를 붙이지 않았어요. 붙일 수 없었다는 편이 정확해요. 첫 글에서 이야기한 대로 계산 장치가 붙은 기계가 한 대뿐이라 늘릴 자리가 없고, 늘릴 수 없으면 자동으로 맞출 것도 없어요.
대신 그 자리를 다른 것이 맡았어요. 부하가 몰려 응답이 늦어지면 개수를 늘리는 대신 대체 경로로 넘겨요. 자원을 늘려 처리량을 맞추는 방식과 넘칠 때 다른 길로 보내는 방식은 목적이 같고 수단이 달라요. 그리고 후자는 늘릴 자리가 없을 때에도 쓸 수 있어요.