Foundry
성능 최적화
기초
핵심

지연 시간과 처리량 (p50/p95/p99)

평균 응답시간은 거짓말한다. p99를 봐야 하는 이유

지연 시간과 처리량

백분위의 의미

지표의미
p50요청 절반이 이보다 빠름 (중앙값)
p9520건 중 1건은 이보다 느림
p99100건 중 1건은 이보다 느림
max최악 1건. 노이즈가 크다

평균이 위험한 이유

응답시간(ms) 10건
50 50 50 50 50 50 50 50 50 4000

평균 445  <- 아무도 겪지 않은 값
p50   50
p90 4000  <- 실제 불만이 나오는 값

실무 포인트

  • 한 화면이 내부 API 10개를 부르면 그중 하나가 꼬리 지연에 걸릴 확률이 커진다. 팬아웃이 클수록 p99가 체감을 지배한다
  • 처리량과 지연은 독립이 아니다. 동시성은 대략 처리량 곱하기 평균 지연이므로, 지연이 2배면 같은 처리량에 커넥션과 스레드가 2배 필요하다
  • 자원이 포화에 가까워지면 지연은 선형이 아니라 급격히 튄다. 여유를 남긴다
  • 백분위는 평균할 수 없다. 서버별 p99를 평균 내지 말고 원본 분포에서 계산한다
면접에서 이렇게 나옵니다

Q.평균 응답시간 대신 p99를 보는 이유는 무엇인가요?

평균은 느린 요청을 숨깁니다. 그리고 사용자는 평균을 경험하지 않습니다.

응답이 100밀리초인 요청 99개와 10초인 요청 1개가 있으면 평균은 199밀리초입니다. 지표는 건강해 보이지만 100명 중 1명은 10초를 기다립니다.

지표보여주는 것
평균전체 경향. 이상값에 흔들린다
p50절반의 사용자가 겪는 시간
p99100명 중 가장 느린 1명의 시간
최댓값한 건의 이상값. 판단에 쓰기 어렵다

한 화면이 여러 API 를 부르면 더 커집니다. API 10개를 부르는 화면이라면 각 API 의 p99 가 1%여도 화면 하나가 느릴 확률은 10%에 가깝습니다. 개별 지표가 좋아 보여도 사용자 체감은 그렇지 않은 이유입니다.

흔한 실수: p99 를 목표로만 두고 p50 을 버리는 것. p50 이 나쁘면 전원이 느린 것이고 원인이 다릅니다. 둘을 함께 봐야 어떤 문제인지 구분됩니다.

Q.p99가 나쁜데 p50은 정상일 때 어떻게 원인을 찾나요?

전체가 느린 것이 아니라 일부 요청만 느린 것입니다. 그 일부의 공통점을 찾습니다.

가설확인 방법
특정 데이터가 크다느린 요청의 파라미터를 본다. 목록 크기, 기간 범위
캐시 미스히트와 미스로 나눠 지연을 비교한다
특정 서버서버별로 나눠 본다. 한 대만 나쁠 수 있다
잠금 경합대기 시간과 동시 요청 수의 관계를 본다
커넥션 풀 대기풀 대기 시간을 별도로 잰다
GC 멈춤GC 로그의 멈춤 시간과 느린 요청 시각을 맞춰본다
콜드 스타트배포 직후나 오래 유휴 후에 몰리는지 본다

순서는 분해하기 쉬운 것부터입니다. 서버별, 엔드포인트별, 사용자별로 나눠 보면 대개 한쪽에 몰려 있습니다. 몰려 있지 않고 고르게 흩어져 있으면 GC 나 잠금처럼 시점 의존적인 원인입니다.

흔한 실수: 평균 자원 사용률을 보고 여유 있다고 판단하는 것. p99 문제는 순간적인 경합이라 1분 평균에서는 보이지 않습니다. 짧은 간격의 지표나 트레이스를 봐야 합니다.

Q.처리량을 높였는데 지연이 나빠지는 이유는?

자원이 포화에 가까워지면 대기 줄이 생기기 때문입니다. 대기 시간은 이용률이 100%에 가까워질수록 급격히 늘어납니다.

이용률대기 시간의 경향
50%처리 시간과 비슷한 수준
80%몇 배로 늘어난다
95%급격히 커진다
100% 근처줄이 무한히 길어진다

그래서 처리량과 지연은 함께 좋아지지 않습니다. 처리량을 끝까지 끌어올리면 지연은 반드시 나빠집니다.

나타나는 자리
커넥션 풀풀이 꽉 차 대기가 생긴다
스레드실행 가능한 스레드가 코어보다 많아 대기한다
디스크와 네트워크큐가 쌓인다
DB잠금 경합과 커넥션 한계

대응은 이용률에 여유를 두는 것입니다. 목표를 60에서 70% 정도로 잡고 그 이상이면 증설합니다. 그리고 처리량 목표와 지연 목표를 함께 정합니다.

흔한 실수: 부하 테스트에서 초당 처리량 최대치만 보고 용량을 정하는 것. 그 지점은 이미 지연이 무너진 곳입니다. 지연 목표를 만족하는 최대 처리량이 실제 용량입니다.

Q.서버 여러 대의 p99를 하나의 값으로 어떻게 집계하나요?

평균하면 안 됩니다. 백분위수는 평균할 수 없는 값입니다.

서버 A 의 p99 가 100밀리초, B 가 500밀리초라고 해서 전체 p99 가 300밀리초인 것이 아닙니다. 전체 p99 는 두 서버의 요청을 모두 합친 분포에서 다시 계산해야 합니다.

방법정확도비용
원본 지연을 모두 모아 계산정확하다저장과 계산 비용이 크다
히스토그램을 합산버킷 폭만큼의 오차실용적. 대부분 이 방식
각 서버 p99 의 최댓값보수적. 과대평가싸다
각 서버 p99 의 평균틀렸다쓰지 않는다

실무에서는 두 번째를 씁니다. 각 서버가 구간별 건수를 히스토그램으로 보고하면 그것을 더해 전체 분포를 만들 수 있습니다. 이것이 합산 가능한 형태로 지표를 남기는 이유입니다.

흔한 실수: 대시보드가 서버별 p99 를 평균해서 보여주는데 그것을 전체 p99 로 읽는 것. 한 서버만 나쁠 때 그 값이 희석되어 문제가 감춰집니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

성능 최적화 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.