Skip to content
isdnetworks
Go back

평균이 감추는 것

성능 개선 작업을 하고 결과를 봤다.

평균 응답 시간: 850ms → 420ms

절반이 됐는데 느리다는 제보는 안 줄었다.

Table of contents

Open Table of contents

분포를 봤다

숫자는 좋아졌는데 쓰는 사람의 느낌이 안 바뀌었다면 그 숫자가 경험을 대표하지 않는다는 뜻이다. 그래서 AVG() 대신 분포를 구간별로 그려 봤다.

구간개선 전개선 후
~200ms40%70%
200~500ms30%20%
500ms~2s25%5%
2s~5%5%

빠른 쪽이 더 빨라져서 AVG() 가 내려간 것이었고 200ms 아래가 40%에서 70%가 됐다.

그런데 2s 를 넘는 5%는 그대로였고 제보하는 사람들이 바로 그 5%다.

표를 만들기 전에는 개선이 전 구간에 고르게 걸린 줄 알았다. 한 칸씩 놓고 보니 어느 구간이 움직였고 어느 구간이 그대로인지가 바로 갈렸다.

같은 자료를 AVG() 하나로 접으면 이 그림이 사라진다. 접기 전의 모양을 한 번은 봐야 했다.

원인 — 다수에 끌려가는 평균

AVG() 는 모든 값을 합쳐 나누므로 많은 쪽이 값을 지배한다. 70%가 200ms 면 그쪽으로 끌린다.

5%가 3초여도 AVG() 에 미치는 영향은 작아서 빠른 쪽만 손봐도 평균은 절반이 된다.

그런데 사용자 경험은 평균으로 안 느껴지고 열 번 중 한 번 3초를 겪으면 느린 서비스다.

숫자가 좋아진 것과 문제가 해결된 것이 다른 이야기인데 AVG() 만 보면 그 둘이 같아 보인다.

개선 보고서에 쓸 숫자로는 AVG() 가 가장 좋아 보이는데 절반이 됐다는 한 줄이 분명하고 짧다.

그 한 줄이 무엇을 말하는지는 분포를 봐야 나오고 보고하기 좋은 숫자와 판단에 쓸 숫자가 달랐다.

백분위로 바꿨다

지표를 백분위로 바꿨다.

p50 (중앙값)   180ms
p90            420ms
p95            890ms
p99           3200ms   ← 여기

p99 가 3.2초였다. 100번 중 한 번은 3초를 넘는다는 뜻이다.

AVG() 로 낸 420ms 와 같은 자료인데 전혀 다른 그림이 나온다. 뒤의 숫자가 남은 문제를 말한다.

이후로 개선 목표를 p95p99 로 잡고 AVG() 는 참고로만 보게 됐다.

백분위로 목표를 잡으면 느린 쪽을 안 건드리고는 숫자가 안 내려간다. 빠른 쪽만 손대면 p99 는 그대로다.

지표를 고르는 것이 곧 무엇을 고칠지를 고르는 일이었다. 평균을 목표로 두면 자연히 다수가 지나가는 경로만 손대게 된다.

느린 5%가 무엇이었나

그 구간을 따로 뽑아 봤더니 공통점이 있었다.

특정 계정      데이터가 많은 대형 고객
특정 조건      필터 없이 전체 조회
특정 시간대    배치가 도는 시각

개선 작업이 일반적인 경우만 빠르게 한 것인데 대형 계정은 캐시가 안 먹는 조건으로 조회한다.

AVG() 를 낮춘 개선이 느린 구간에는 손을 안 댔고 그쪽은 다른 경로를 타고 있었다.

WHERE 로 뽑아 보지 않으면 느린 것이 흩어져 보이고 몰린 자리를 찾는 것이 조사의 대부분이었다.

판단 기준 — 무엇을 측정할지

이 경험 이후로 성능 작업 전에 두 가지를 정한다. 무엇을 개선하려는지와 누구의 경험인지다.

전체 처리량 → 평균과 초당 처리 건수
사용자 체감 → p95·p99
최악의 경우 → 최댓값과 그 조건

목표에 따라 봐야 할 지표가 갈리는데 전체 AVG() 는 다수의 경험이라 대형 사용자가 거기 안 나타난다.

그래서 대형 계정만 따로 지표를 뽑았는데 전체에 섞으면 그 계정들이 통계적으로 사라진다.

주의 — 표본 수라는 조건

백분위를 볼 때 주의할 것이 하나 더 있는데 표본이 적으면 p99 가 의미가 없다.

100건 중 p99 는 두 번째로 느린 것 하나라 우연히 느렸을 수 있어서 지표에 COUNT(*) 를 함께 뒀다.

p99  3200ms  (n=48,203)
p99  1100ms  (n=37)      ← 이건 못 믿는다

시간대를 잘게 쪼개면 이런 구간이 생긴다. 새벽처럼 요청이 적은 때가 그렇다.

표본이 적은 구간에는 같은 기준을 안 적용했는데 숫자가 나온다고 다 같은 무게가 아니다.

COUNT(*) 를 안 적어 두면 두 줄이 똑같이 보인다. 같은 p99 이름에 단위까지 같기 때문이다.

옆에 붙은 n 하나가 그 숫자를 믿을지를 정했고 지표에 표본 수를 붙이는 것이 습관이 됐다.

정리


Share this post on:

Previous Post
지운 캐시가 그 캐시가 아니었다
Next Post
검색 결과와 DB가 다를 때