사전 스파이크 테스트
개념

스파이크 테스트

gabury1고친 사람 github-actions[bot]

스파이크 테스트는 시스템에 거는 부하를 한순간에 확 올렸다가 다시 뚝 내려 봅니다. 사용자가 갑자기 몰리는 순간을 버티는지 미리 알아냅니다. 몰림이 지나간 뒤 제 상태로 돌아오는지도 봅니다. 부하가 얼마나 큰지보다 얼마나 빨리 오르는지를 보는 시험입니다.

쉽고 빠른 이해

요청을 평소 수준으로 보내다가 한순간에 몇 배로 늘려 보는 시험입니다. 잠시 뒤에는 다시 줄입니다. 공연 예매가 열리는 정각에 사용자가 한꺼번에 들이닥치는 상황을 미리 흉내 냅니다.

사용자가 천천히 늘 때는 버티던 시스템도, 한꺼번에 몰리면 넘어질 수 있습니다. 서버를 더 띄우고 연결을 새로 여는 일에는 시간이 걸립니다. 몰림은 그 시간을 기다려 주지 않습니다.

어떻게 하나:

  1. 평소 수준의 요청을 걸어 두고 응답 시간과 오류를 읽습니다
  2. 요청을 한순간에 몇 배로 올려 짧게 유지합니다
  3. 다시 평소로 내리고, 제 상태로 돌아오기까지 얼마나 걸리는지 봅니다

부하를 만드는 쪽도 한순간에 그만큼을 쏟아낼 수 있어야 합니다. 운영 중인 서비스에 걸면 사용자가 피해를 봅니다. 운영 환경을 본뜬 시험 환경을 따로 갖추는 비용이 드는 까닭입니다.

상세

한적하던 식당 앞에 관광버스 한 대가 섭니다. 손님 마흔 명이 한꺼번에 들어옵니다. 주방은 그 몇 분 동안 주문을 따라가지 못합니다. 버스가 떠난 뒤에도 밀린 주문을 다 내기까지는 한참이 걸립니다.

시스템에 한꺼번에 걸리는 일감의 양을 부하라고 합니다. 웹 서비스라면 대개 동시에 들어오는 요청 수로 잽니다. 스파이크 테스트는 이 부하를 평소 수준에서 갑자기 크게 올렸다가 다시 떨어뜨립니다. 그 급변을 시스템이 견디는지 보는 시험입니다.

급변은 정해진 순간에 찾아올 때가 많습니다. 공연 예매가 열리는 정각, 선착순 할인이 시작되는 순간, 앱 알림이 수십만 명에게 한꺼번에 나간 직후가 그렇습니다. 이런 때는 몇 초 사이에 요청이 평소의 몇 배로 뜁니다.

같은 양의 부하라도 천천히 오를 때는 버티던 시스템이, 한꺼번에 오르면 넘어질 수 있습니다. 시스템이 부하에 맞춰 스스로 늘어나고 준비하는 데에는 시간이 걸리기 때문입니다. 몰림은 그 시간을 기다려 주지 않습니다.

부하 테스트와 스트레스 테스트는 대개 부하를 서서히 올립니다. 그래서 시스템이 스스로 늘어나기까지 걸리는 시간, 이 빈틈이 잘 안 보입니다. 이 빈틈을 모른 채 두면 실제 사용자가 몰리는 날에 처음 만나게 됩니다. 스파이크 테스트는 부하가 오르는 속도 자체를 시험 조건으로 삼아 이 빈틈을 드러냅니다.

부하를 거는 모양

이 소절은 시간에 따라 부하를 어떻게 거는지를 봅니다. 서서히 올리는 스트레스 테스트와 나란히 놓으면 차이가 잘 보입니다.

먼저 평소 수준의 부하를 한동안 걸어 비교할 기준값을 잡습니다. 그다음 거의 한순간에 몇 배로 올립니다. 그 부하를 짧게 유지합니다. 다시 평소 수준으로 떨어뜨린 뒤에도 부하를 끊지 않고 한동안 더 겁니다.

부하를 만드는 도구는 요청을 보내는 가짜 사용자를 여럿 띄웁니다. 이 가짜 사용자 하나하나를 가상 사용자라고 부릅니다. 아래 그림은 시간에 따라 가상 사용자 수를 바꾸는 모양을 두 시험에 대해 나란히 보입니다.

xychart-beta
    title "시간에 따라 거는 부하의 모양"
    x-axis ["0분", "2분", "4분", "6분", "8분", "10분", "12분", "14분", "16분"]
    y-axis "가상 사용자 수" 0 --> 1100
    line [100, 100, 100, 1000, 1000, 100, 100, 100, 100]
    line [100, 200, 300, 400, 500, 600, 700, 800, 900]

뾰족하게 솟았다가 떨어지는 선이 스파이크 테스트입니다. 비스듬히 꾸준히 오르는 선이 스트레스 테스트입니다. 두 시험 모두 큰 부하를 겁니다. 다른 것은 오르는 속도입니다.

스트레스 테스트는 부하를 조금씩 올릴 때마다 시스템이 따라올 틈을 줍니다. 스파이크 테스트는 그 틈을 주지 않습니다. 몇 분 만에 끝나는 스파이크 동안 시스템이 무엇을 놓치는지를 봅니다.

스파이크를 한 번만 걸지 않고 몇 번 되풀이하기도 합니다. 첫 스파이크 때 밀린 요청이 다음 스파이크 전에 다 처리되는지를 함께 봅니다.

시험이 알아내는 세 가지

스파이크 테스트는 솟는 순간, 솟은 채 머무는 동안, 가라앉은 뒤를 따로 봅니다. 셋이 알려 주는 것이 다릅니다.

첫째는 솟는 순간 버티는가입니다. 요청 가운데 실패한 것의 비율을 오류율이라고 합니다. 몰림이 시작된 첫 몇 초에 이 값이 튀는지 봅니다.

요청을 보내고 답을 받기까지 걸리는 시간은 응답 시간입니다. 몰림 동안 이 값이 얼마나 늘어나는지도 같이 읽습니다.

둘째는 늘어나는 장치가 제때 따라오는가입니다. 부하를 보고 서버 수를 자동으로 늘리고 줄이는 장치를 오토스케일링이라고 합니다. 몰림이 시작되고 얼마 뒤에 새 서버가 일을 받기 시작하는지를 잽니다. 그 사이의 틈이 이 시험이 찾는 핵심 값입니다.

셋째는 가라앉은 뒤 돌아오는가입니다. 부하를 내린 뒤 오류율과 응답 시간이 평소 값으로 돌아오기까지 걸리는 시간을 적습니다. 늘어난 서버가 다시 줄어드는지도 봅니다. 줄지 않으면 할 일 없는 서버에 비용을 계속 냅니다.

급변 앞에서 늦는 장치

시스템에는 부하에 맞춰 스스로 늘어나거나 채워지는 장치가 여럿 있습니다. 이 장치들은 모두 따라가는 데 시간이 걸립니다. 스파이크 테스트가 드러내는 것은 대개 이 시간입니다.

오토스케일링은 몰림을 알아채고 서버를 새로 띄워 일을 나눠 받게 합니다. 사용량을 모아 몰림이라고 판단하는 데 한 번, 새 서버가 켜져 요청을 받을 준비를 마치는 데 또 한 번 시간이 듭니다. 그동안 들어오는 요청은 원래 있던 서버가 모두 받아야 합니다.

sequenceDiagram
    participant U as 사용자들
    participant O as 기존 서버
    participant A as 오토스케일링
    participant N as 새 서버
    U->>O: 요청이 한꺼번에 몰린다
    A->>O: 사용량을 읽는다
    Note over A: 몰림이라고 판단한다
    A->>N: 서버를 띄운다
    Note over O: 그동안 혼자 받느라 느려지고 요청을 놓친다
    N-->>A: 준비를 마쳤다
    U->>N: 요청이 나뉘어 들어온다

그림에서 「요청이 한꺼번에 몰린다」부터 「준비를 마쳤다」까지가 기존 서버 혼자 버티는 구간입니다. 몰림이라고 판단하는 시간과 새 서버가 준비하는 시간이 둘 다 이 구간에 들어갑니다.

이 구간이 길면 새 서버가 준비를 마치기 전에 몰림이 끝나 버립니다. 그러면 늘린 서버는 할 일이 없습니다. 요청은 이미 실패한 뒤입니다.

새로 뜬 서버는 켜지자마자 제 속도를 내지 못하기도 합니다. 필요한 것을 처음으로 읽어 들이고 준비하느라 첫 요청들이 느립니다. 이 현상을 콜드 스타트라고 합니다. 몰림 한가운데서 콜드 스타트가 겹치면 서버를 늘린 효과가 그만큼 늦게 나타납니다.

데이터베이스와 연결을 맺는 일에는 시간이 듭니다. 그 시간을 아끼려고 연결을 미리 몇 개 열어 놓고 돌려 씁니다. 이 묶음을 커넥션 풀이라고 합니다.

요청이 한꺼번에 몰리면 열어 둔 연결이 순식간에 동납니다. 뒤에 온 요청은 연결이 빌 때까지 줄을 섭니다.

자주 읽는 값을 가까이 복사해 두는 곳을 캐시라고 합니다. 값의 원래 주인은 데이터베이스 같은 원본 저장소입니다. 캐시에 값이 있으면 원본까지 가지 않아도 됩니다.

캐시도 급변에 약합니다. 캐시가 비어 있는 채로 몰림을 맞으면 요청들이 캐시에서 값을 찾지 못합니다. 그 요청들은 모두 원본 저장소로 갑니다. 같은 값을 찾는 요청이 원본으로 한꺼번에 쏟아지는 이 일을 캐시 스탬피드라고 부릅니다.

몰림이 지나간 뒤

부하를 내렸다고 시험이 끝나지 않습니다. 몰림이 남긴 일감이 한동안 시스템에 남기 때문입니다. 까닭은 둘입니다.

먼저 대기 줄이 남습니다. 새로 들어오는 요청은 평소 수준으로 줄었습니다. 그래도 앞서 줄을 선 요청을 다 처리하기 전까지 응답은 계속 늦습니다.

요청을 보낸 쪽은 정해 둔 시간 안에 답이 안 오면 기다리기를 멈춥니다. 이 시간 한도를 타임아웃이라고 합니다. 몰림 동안에는 많은 요청이 타임아웃에 걸려 실패합니다.

실패한 요청은 대개 다시 보내집니다. 이것을 재시도라고 합니다. 몰림 동안 실패한 요청들이 한꺼번에 다시 오면, 부하를 내린 뒤에도 서버에는 몰림이 이어집니다. 그래서 부하를 내린 뒤 얼마 만에 제 상태로 돌아오는지가 이 시험의 중요한 결과입니다.

이웃한 시험과 가르는 선

부하를 걸어 속도와 버티는 힘을 재는 시험을 통틀어 성능 테스트라고 합니다. 그 안의 시험들은 거는 방법이 비슷해서 이름이 섞여 쓰입니다. 아래 표는 부하를 거는 모양과 알아내려는 것으로 넷을 가릅니다.

시험 부하를 거는 모양 알아내는 것
부하 테스트 예상 최대까지 서서히 올려 유지 예상 범위를 감당하나
스트레스 테스트 한계를 넘을 때까지 조금씩 올림 어디서 어떻게 무너지나
스파이크 테스트 한순간에 치솟았다가 떨어뜨림 급변을 견디고 돌아오나
소크 테스트 보통 부하를 오래 시간이 갈수록 쌓이는 문제가 있나

제일 헷갈리는 짝은 스트레스 테스트입니다. 둘 다 평소보다 큰 부하를 걸기 때문입니다. 가르는 기준은 크기가 아니라 속도입니다. 한계보다 낮은 부하라도 한순간에 걸면 스파이크 테스트입니다.

시험이 필요한 서비스와 드는 비용

몰림이 예고된 서비스가 첫째입니다. 예매, 선착순 판매, 대량 알림 발송이 그렇습니다. 이런 서비스는 몰림이 오는 시각까지 미리 알 때가 많습니다.

오토스케일링에 기대는 서비스가 둘째입니다. 늘어나는 장치가 제때 따라오는지는 서서히 올리는 시험으로는 잘 안 보입니다.

반대로 요청이 늘 고르게 들어오는 내부 서비스에는 급변이 올 일이 드뭅니다. 이 시험으로 얻는 것도 적습니다.

부하를 만드는 쪽도 한순간에 그만큼을 쏟아낼 수 있어야 합니다. 부하를 만드는 도구와 장비를 부하 생성기라고 합니다. 부하 생성기가 가상 사용자를 한꺼번에 띄우지 못하면 오르는 선이 저절로 완만해집니다. 그러면 시험이 더 이상 스파이크가 아닙니다.

운영 중인 서비스에 걸면 시험이 곧 장애가 됩니다. 그래서 대개 운영 환경을 본뜬 시험 환경을 따로 두고 겁니다. 오토스케일링 설정까지 운영 환경과 같아야 오토스케일링이 따라오기까지 걸린 시간을 믿을 수 있습니다. 시험 환경을 운영 환경에 얼마나 가깝게 만들지와 그 비용 사이에서 고르는 것이 이 시험의 대가입니다.

관련 항목

스파이크 테스트와 목적이 갈리는 성능 시험

성능 테스트 · 부하 테스트 · 스트레스 테스트 · 소크 테스트 · 스모크 테스트 · 벤치마크 · 카오스 엔지니어링

스파이크를 만들어 거는 도구와 설정값

k6 · Locust · JMeter · Gatling · 부하 생성기 · 가상 사용자 · 램프업

스파이크를 견디는지 읽는 지표

응답 시간 · 오류율 · 처리량 · 백분위수 · 지연 · 초당 요청 수 · 회복 시간

부하를 따라 늘어나거나 채워지는 구성 요소

오토스케일링 · 수평 확장 · 로드 밸런서 · 커넥션 풀 · 캐싱 · 워밍업

몰림 때 드러나는 느려짐과 고장

콜드 스타트 · 캐시 스탬피드 · 썬더링 허드 · 커넥션 풀 고갈 · 재시도 폭풍 · 연쇄 장애

요청을 보낸 쪽이 몰림 속 실패에 맞서는 방식

타임아웃 · 재시도 · 지수 백오프 · 서킷 브레이커

스파이크를 누그러뜨리려고 서버 쪽에 두는 장치

속도 제한 · 스로틀링 · 백프레셔 · 대기열 · 우아한 저하

시험 결과를 받아 쓰는 운영 작업

용량 계획 · 모니터링 · 경보 · SLO · 성능 기준선 · 성능 회귀

다른 이름: spike testing · spike test · 스파이크 시험