부하 테스트
시스템에 일감을 잔뜩 걸어 놓고 그 상태에서 어떻게 도는지 재는 시험입니다. 한 사람이 한 번 눌러 볼 때는 보이지 않던 것이 여럿이 한꺼번에 몰릴 때 드러납니다. 그 자리를 실제 사용자가 몰리기 전에 미리 보자는 것입니다.
상세
다리를 놓고 나면 개통 전에 트럭을 줄줄이 올려 봅니다. 계산상 견딘다는 것과 실제로 올려 봤을 때가 같은지 확인하는 것입니다.
부하 테스트는 예상되는 만큼의 일감을 실제로 걸어 놓고 그 상태의 거동을 재는 일입니다. Amazon Web Services 의 규범 지침 문서는 부하 시험이 애플리케이션이 기대한 품질을 내고 있는지에 대한 믿을 만한 정보를 얻으려고 하는 것이라고 적습니다. 무엇을 걸었는지와 그때 무슨 값이 나왔는지가 짝으로 남아야 시험이 됩니다.
부하를 세는 단위
무엇을 부하라고 셀지부터 정합니다. AWS 문서는 시험을 짜기 전에 초당 요청 수로 잴지, 초 단위 응답 시간으로 잴지, 동시 사용자 수로 잴지를 먼저 정하라고 적습니다. 그리고 애플리케이션의 어느 부분을 시험 대상으로 삼을지도 정하라고 적습니다.
거는 쪽에서는 사람 한 명 몫의 흐름을 가상 사용자라는 단위로 셉니다. Microsoft 가 낸 부하 시험 개념 문서는 가상 사용자를 특정 시험 사례를 서버 애플리케이션에 대해 수행하는 것이라고 적습니다. 다른 가상 사용자와 독립적으로 돈다고 덧붙입니다. 여럿을 두면 동시 연결을 흉내 낼 수 있습니다. 목표한 가상 사용자 수를 다 채우기까지 쓰는 시간은 램프업 시간이라고 부릅니다.
초당 요청 수는 RPS(Requests Per Second, 초당 요청 수)라고 씁니다. 같은 문서는 이것을 처리량이라고도 부릅니다. 요청 수를 전체 초로 나눈 값이라고 적습니다. 지연을 알면 반대로도 계산합니다. 가상 사용자 수는 목표 RPS 에 초 단위 지연을 곱한 값입니다.
거는 쪽과 받는 쪽
값은 양쪽에서 나옵니다. 같은 문서는 시험 엔진이 보고하는 값을 클라이언트 쪽 지표로, 대상 애플리케이션 구성 요소에서 나오는 값을 서버 쪽 지표로 가릅니다. 앞쪽에는 가상 사용자 수와 요청 응답 시간과 실패한 요청 수와 초당 요청 수가 듭니다.
flowchart TD
A["부하 생성기"] -->|"가상 사용자"| B["대상 시스템"]
B -->|"응답"| A
A --> C["거는 쪽에서 잰 값"]
B --> D["받는 쪽에서 잰 값"]
부하 생성기가 가상 사용자 수만큼의 흐름을 만들어 대상 시스템에 요청을 보냅니다. 응답이 돌아오는 데 걸린 시간과 실패한 요청 수는 거는 쪽이 셉니다. 그 사이 대상 시스템의 자원이 어떻게 움직였는지는 받는 쪽이 셉니다. 둘을 나란히 놓아야 어느 값이 왜 그렇게 나왔는지를 짚을 수 있습니다.
부하를 올리는 두 방식
같은 양을 걸어도 어떻게 올렸느냐에 따라 결과가 달라집니다. Google SRE Book 은 캐시 효과 때문에 부하를 점진적으로 올리는 것이 예상 수준으로 즉시 올리는 것과 다른 결과를 낼 수 있다고 적습니다. 그래서 점진적인 부하 형태와 충격적인 부하 형태를 둘 다 시험해 보라고 덧붙입니다.
걷은 뒤도 봅니다. 같은 문서는 구성 요소를 정상 부하보다 훨씬 위로 밀어 놓았다가 정상 부하로 돌아올 때 어떻게 행동하는지도 시험해 이해해야 한다고 적습니다. 높은 부하에서 성능 저하 상태로 들어간 구성 요소가 사람 손을 빌리지 않고 그 상태를 빠져나올 수 있는지가 그 시험이 답하는 물음입니다.
배경
기능이 맞는지 보는 시험은 한 번에 하나씩 부릅니다. 요청 하나를 넣고 답이 맞는지 봅니다. 여럿이 동시에 몰릴 때만 생기는 일은 그 시험에 걸리지 않습니다. 큐가 차고 스레드가 묶이고 연결이 바닥나는 자리는 요청 하나로는 만들어지지 않기 때문입니다.
코드를 읽어서 미리 알아내기도 어렵습니다. Google SRE Book 은 서비스가 실패하는 구체적인 방식은 제일원리에서 예측하기가 매우 어려울 수 있다고 적습니다. 그래서 높은 부하에서 어떻게 행동하는지 시험해 보라고 적습니다. 같은 문서는 용량 계획이 성능 시험과 짝을 이루어야 한다고도 적습니다. 서비스가 무너지는 부하가 얼마인지를 알아야 몇 벌을 띄울지 계산이 서기 때문입니다.
이름은 그 갈림에서 나옵니다. Microsoft 의 Azure Well-Architected Framework 문서는 성능 시험을 비기능 시험 관행이라고 적습니다. 워크로드가 여러 조건에서 어떻게 행동하는지를 평가하는 자리라고 적습니다. 기능 시험을 넘어서는 평가를 가능하게 한다고 덧붙입니다. 그 안에서 예상되는 사용자 수를 감당하는지 확인하는 시험에 부하 테스트라는 이름이 붙습니다.
예시
ab
Apache HTTP Server 2.4 가 같이 배포하는 명령입니다. 공식 문서는 ab(ApacheBench)를 Apache HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 규약) 서버를 벤치마킹하는 도구라고 적습니다. 지금 설치된 Apache 가 초당 몇 건의 요청을 처리할 수 있는지를 특히 잘 보여 준다고 적습니다. 부하를 정하는 인자는 이렇습니다.
-c concurrency 한 번에 수행할 요청 수. 기본값은 한 번에 하나
-n requests 이번 벤치마킹 세션에서 수행할 요청 수. 기본값은 한 건
-t timelimit 벤치마킹에 쓸 최대 초. 이 값을 주면 내부적으로 -n 50000 이 걸린다
-k HTTP keepalive 를 켠다. 기본값은 끔
-s timeout 소켓이 시간 초과될 때까지 기다리는 최대 초. 기본값 30
-c 와 -n 이 앞 절의 동시성과 요청 수에 해당합니다. 문서는 -n 의 기본값이 한 건이라
그대로 쓰면 대표성이 없는 결과가 나온다고 적어 둡니다. 결과로 나오는 항목 이름은 Concurrency
Level, Time taken for tests, Complete requests, Failed requests, Requests per second,
Time per request 입니다. 마지막 값은 요청 하나에 평균으로 든 시간입니다.
같은 문서의 Bugs 절에는 이런 문장이 있습니다. strstr(3) 을 무겁게 쓰는 탓에 프로파일 맨
위에 올라오며, 이는 성능 문제를 뜻할 수 있다는 것입니다. 그러면 서버가 아니라 ab 자신의
성능을 재게 된다고 적습니다. 부하를 거는 쪽이 먼저 한계에 닿으면 재는 대상이 뒤바뀝니다.
같은 자리를 인프라 쪽에서 적은 문서도 있습니다. Amazon Web Services 의 부하 시험 지침 문서는 부하 시험이 대개 많은 대역폭을 쓴다고 적습니다. 네트워크 업로드가 병목이 되지 않을 만큼의 대역폭을 주라고 적습니다. 부하를 만드는 서버가 부하를 받는 애플리케이션 서버보다 수가 적은 경우가 대부분이라, 시험용 서버 쪽이 대역폭을 더 요구한다고 덧붙입니다.
pgbench
PostgreSQL 18 이 같이 배포하는 명령입니다. 공식 문서는 pgbench 를 PostgreSQL 에서 벤치마크 시험을 돌리는 단순한 프로그램이라고 적습니다. 같은 SQL(Structured Query Language, 구조화 질의 언어) 명령 묶음을 되풀이해 수행한다고 적습니다. 여러 개의 동시 데이터베이스 세션에서 그렇게 할 수 있다고 덧붙입니다. 그리고 평균 트랜잭션 처리율을 계산합니다. 문서가 싣고 있는 출력은 이렇습니다.
transaction type: <builtin: tpc-b (sort of)>
scaling factor: 10
query mode: simple
number of clients: 10
number of threads: 1
maximum number of tries: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
number of failed transactions: 0 (0.000%)
latency average = 11.013 ms
latency stddev = 7.351 ms
initial connection time = 45.758 ms
tps = 896.967014 (without initial connection time)
클라이언트 10 개가 각각 1000 건씩, 모두 10000 건을 수행했습니다. 평균 지연은 11.013
밀리초이고 초당 트랜잭션 수는 896.967014 입니다. 부하를 정하는 인자로 문서가 가장 중요하다고
꼽는 것은 -c(클라이언트 수)와 -t(트랜잭션 수)와 -T(시간 제한)와 -f(직접 쓴 스크립트
파일)입니다. 기본 시나리오는 TPC-B(Transaction Processing Performance Council Benchmark B)에
느슨하게 기반한 것으로, 트랜잭션 하나에 SELECT 와 UPDATE 와 INSERT 다섯 개가 듭니다.
문서에는 주의 문구도 붙어 있습니다. pgbench -i 는 pgbench_accounts, pgbench_branches,
pgbench_history, pgbench_tellers 네 테이블을 만들면서 같은 이름의 기존 테이블을 파괴한다는
것입니다. 그 이름의 테이블이 있다면 다른 데이터베이스를 쓰라고 적습니다.
Azure Load Testing
Microsoft 가 운영하는 관리형 부하 시험 서비스입니다. 그 개념 문서에는 가상 사용자 수를 목표 초당 요청 수에서 거꾸로 계산한 실제 값이 실려 있습니다. 애플리케이션 지연이 20 밀리초, 곧 0.02 초라고 할 때 100,000 RPS 를 흉내 내려면 가상 사용자를 2,000 으로 잡으라고 적습니다. 100,000 에 0.02 를 곱한 값입니다.
램프업 시간도 값으로 보입니다. 가상 사용자가 20 이고 램프업 시간이 120 초이면 20 명을 다 채우는 데 120 초가 걸립니다. 각 가상 사용자는 앞 사용자가 시작한 뒤 6 초 있다가 시작합니다. 120 을 20 으로 나눈 값입니다.
경계
예상 범위를 넘겨 무너질 때까지 거는 것도 부하 테스트인가. 아닙니다. 그건 스트레스 테스트로 따로 세웁니다.
가르는 선은 목적입니다. Microsoft 의 Azure Well-Architected Framework 문서는 시험 유형 표에서 부하 테스트를 "시스템이 정상 사용과 최대 사용에서 예상되는 사용자 규모를 감당하는지 확인"하는 자리로 적습니다. 그리고 스트레스 테스트를 "시스템의 한계와 무너지는 지점을 이해"하는 자리로 적습니다. 무엇이 드러나는지도 갈라 적습니다. 앞쪽은 기준선 성능과 용량 한계와 확장이 듣는지를, 뒤쪽은 최대 용량과 실패 방식과 복구 거동을 드러낸다고 적습니다. 같은 표는 스파이크 테스트와 내구성 테스트도 나란히 세웁니다.
이름이 겹쳐 쓰이는 것은 사실입니다. Google SRE Book 은 "구성 요소가 깨질 때까지 부하를 걸어라"라고 적어, 한계 너머까지 미는 행위에도 부하 시험이라는 말을 씁니다. 그래도 판정은 목적으로 합니다. 예상 부하를 감당하는지 확인하려는 것이면 부하 테스트입니다. 무너지는 지점을 찾는 것이 목적이면 그 이름을 따로 씁니다.
관련 항목
부하 크기를 정하는 값
초당 요청 수 · 동시 사용자 · 가상 사용자 · 램프업 시간
부하 테스트가 재는 지표
처리량 · 응답 시간 · 지연 · 오류율 · 성능 기준선 · 성능 회귀 · 합성 트랜잭션 · 백분위수
나란히 서는 시험
스트레스 테스트 · 스파이크 테스트 · 내구성 테스트 · 벤치마크 · 기능 시험 · 카나리 배포
부하 테스트에서 자주 나는 오류·장애
병목 · 백프레셔 · 큐 대기 · 커넥션 풀 고갈 · 메모리 누수 · 연쇄 장애 · 썬더링 허드 · 캐시 스탬피드 · 성능 저하
부하 테스트 중 상태를 보는 수단
용량과 목표를 정하는 기준
서비스 수준 목표 · 서비스 수준 지표 · 오류 예산 · 용량 계획
부하를 견디도록 돕는 장치
부하를 만드는 도구
JMeter · k6 · Locust · ab · pgbench · TPC-B · 부하 생성기 · Azure Load Testing
다른 이름: load testing · load test · 로드 테스트