부하 테스트는 통과했는데 운영에서 무너지는 6가지 이유
출시 전 부하 테스트에서 목표의 세 배를 버텼는데, 실제로는 목표치에서 무너졌어요. 테스트가 틀린 게 아니라 조건이 달랐던 거예요. 시험에서 빠지기 쉬운 여섯 가지 조건과 넣는 법을 정리했어요.
출시 전에 부하 테스트를 했어요. 목표 트래픽의 세 배까지 무리 없이 통과했고, 응답 시간도 안정적이었어요.
그런데 실제 출시하니 목표 트래픽에서 무너졌어요. 테스트에서 통과한 수치의 3분의 1에서요.
테스트가 거짓말을 한 게 아니에요. 테스트한 상황과 실제 상황이 달랐던 거예요.
부하 테스트는 대개 가장 좋은 조건에서 이뤄져요. 데이터도 적고, 요청도 고르고, 캐시도 예열돼 있고, 의존성도 항상 정상이에요.
그래서 통과했다는 사실이 실제로 견딘다는 뜻은 아니에요. 무엇을 빼고 시험했는지를 알아야 그 결과를 해석할 수 있습니다.
왜 그런가
부하 테스트가 실제와 달라지는 지점들이 있어요.
데이터 크기. 테스트 DB 는 대개 작아요. 데이터가 적으면 전부 캐시에 들어가고 인덱스도 얕아요. 앞 편에서 본 대로 인덱스 선택도 계획도 데이터 양에 따라 달라져요. 운영 규모의 데이터가 없으면 다른 시스템을 시험한 거예요.
접근 분포. 테스트는 대개 무작위로 흩뿌려요. 실제는 앞 편에서 본 대로 극단적으로 치우쳐요. 인기 항목 하나에 요청이 몰리는 상황이 재현되지 않으면 핫 키 문제를 못 잡아요.
부하의 모양. 대개 서서히 올려요. 실제 급증은 순간적이에요. 앞 편에서 본 대로 오토스케일과 캐시가 따라오지 못하는 구간이 그때 생기는데, 계단식 테스트로는 안 나타나요.
캐시 상태. 테스트는 예열된 상태에서 재는 경우가 많아요. 실제로 문제가 되는 건 캐시가 비었을 때고요.
의존성. 외부 서비스를 흉내 낸 가짜 서버는 항상 빠르게 정상 응답해요. 실제로는 느려지고, 실패하고, 앞 편에서 본 재시도 증폭이 시작됩니다.
기간. 몇 분만 돌리면 서서히 나빠지는 것들을 못 봐요. 메모리 누수, 연결 누수, 큐 적체, 디스크 소진은 시간이 걸립니다.
코드로 보면
빠진 조건을 하나씩 넣는다:
· 1) 운영 규모의 데이터
데이터 양이 계획과 지표를 바꾼다
· 2) 실제 접근 분포
무작위 균등 → 실제는 극단적으로 치우친다
상위 몇 개 키에 요청을 몰아 보는 시나리오
· 3) 순간 급증
계단식으로 올리면 오토스케일·캐시가 따라온다
0 → 목표치를 몇 초 만에 올리는 시나리오
· 4) 차가운 캐시
캐시를 비우고 시작하는 회차를 따로 둔다
· 5) 의존성 장애 주입
외부 API 를 느리게 · 실패하게 만들어 본다
· 6) 오래 돌린다
몇 시간 이상 — 누수와 적체는 시간이 걸린다✕ 문제 지점 · ✓ 해법 · 그대로 돌려 보기 전에 자기 환경에 맞게 고쳐 주세요.
실전에서는
무엇을 확인하려는지에 따라 테스트 종류가 달라져요.
용량을 알고 싶으면 부하를 서서히 올리며 처리량이 평평해지는 지점을 찾아요. 그 지점이 그 시스템의 한계고, 그보다 여유를 두고 운영해야 해요.
급증을 견디는지 알고 싶으면 순간적으로 올려야 해요. 이때 보는 건 처리량이 아니라 회복 시간이에요. 얼마나 빨리 정상으로 돌아오는가.
한계를 넘었을 때 어떻게 되는지도 봐야 해요. 이게 특히 중요해요. 용량을 넘으면 무너지는 게 아니라 우아하게 나빠져야 해요. 앞 편에서 본 부하 흘리기가 동작하는지, 일부만 실패하고 나머지는 정상인지요. 전면 붕괴하면 그 시스템은 준비가 안 된 거예요.
오래 돌리는 테스트도 필요해요. 메모리 누수, 연결 누수, 디스크 소진, 큐 적체는 짧은 테스트로 절대 안 나와요.
그리고 의존성 장애 주입이 중요해요. 실제 장애의 상당수는 부하 자체가 아니라 의존성이 느려지면서 시작돼요. 앞 편들에서 본 재시도 증폭, 커넥션 고갈, 서킷 브레이커 동작이 그때 시험됩니다.
여기서 원칙이 하나 나와요. 테스트는 통과하려고 하는 게 아니라 무너뜨리려고 하는 거예요. 통과하는 테스트만 돌리면 아무것도 배우지 못해요. 어디서 어떻게 무너지는지를 알아야 대비할 수 있습니다.
측정 쪽도 봐야 해요. 부하를 주는 도구 자체가 병목이 되면 잘못된 결과가 나와요. 그리고 앞 편에서 본 대로 평균이 아니라 분포를 봐야 하고요.
처방
- 운영 규모의 데이터로 하세요. 데이터 양이 계획과 지표를 바꿉니다.
- 실제 접근 분포를 재현하세요. 무작위 균등은 현실과 다릅니다.
- 순간 급증 시나리오를 따로 만드세요. 계단식만으로는 못 잡습니다.
- 캐시가 빈 상태에서도 재세요. 문제가 되는 건 그 순간입니다.
- 의존성을 느리게 만들어 보세요. 실제 장애의 상당수가 여기서 시작됩니다.
- 몇 시간 이상 돌리는 회차를 두세요. 누수와 적체는 시간이 걸립니다.
- 한계를 넘겼을 때 어떻게 되는지 보세요. 우아하게 나빠지는지, 전면 붕괴하는지가 핵심입니다.
- 무너뜨리려고 테스트하세요. 통과만 확인하면 아무것도 배우지 못합니다.
- 부하 생성기 자체가 병목은 아닌지 확인하세요. 생성기가 먼저 한계에 걸리면 목표 부하가 실제로 가지 않은 채 '문제없음' 으로 나옵니다.
- 환경이 운영보다 작으면 절대 수치를 믿지 마세요. 대신 어제보다 나빠졌는지 같은 상대적 변화를 보는 용도로 쓰세요.
지금 확인해 보세요
테스트가 실제와 무엇이 다른가:
· 목록으로 확인한다
데이터 양이 운영 규모인가
접근 분포가 치우쳐 있는가
급증 시나리오가 있는가
캐시가 빈 회차가 있는가
의존성을 느리게 만들어 봤는가
몇 시간 이상 돌린 회차가 있는가
· 부하 생성기가 병목은 아닌가
생성기의 CPU · 네트워크 · 연결 수를 함께 본다
· 한계를 넘겼을 때의 동작
전면 붕괴하면 준비가 안 된 것이다
일부 거절 + 나머지 정상이 목표다
· 회복 시간
부하를 걷었을 때 정상으로 돌아오는 데 걸리는 시간핵심 한 줄테스트는 통과하려고 하는 게 아니라 무너뜨리려고 하는 것이다.