상대오차 분위수 스케치(로그 버킷) 계산기
지연시간처럼 여러 자릿수에 걸친 값을 담을 때 필요한 로그 버킷의 개수와 메모리를 구합니다. 버킷 비 γ = (1+α)/(1−α)로 상대오차를 고정하는 DDSketch 방식이며, 같은 범위를 등간격으로 담을 때와 나란히 비교해 줍니다.
단위는 자유입니다. 지연시간이면 ms로 두고 쓰면 됩니다.
같은 범위를 등간격으로 담으면 몇 칸이 필요한지 비교합니다.
상대오차 2%를 보장하는 버킷 수
289칸
같은 범위를 등간격으로 담으면 99,999칸이 필요합니다 — 346배 차이입니다. 메모리는 2.26KB로 추정됩니다.
버킷을 펼쳐 보면
| 번호 | 아래 끝 | 위 끝 | 폭 | 대표값 | 상대오차 |
|---|---|---|---|---|---|
| 0 | 0.9608 | 1 | 0.0392 | 0.98 | ±2% |
| 1 | 1 | 1.0408 | 0.0408 | 1.02 | ±2% |
| 2 | 1.0408 | 1.0833 | 0.0425 | 1.0616 | ±2% |
| 3 | 1.0833 | 1.1275 | 0.0442 | 1.105 | ±2% |
| 144 | 305.1376 | 317.5922 | 12.4546 | 311.2404 | ±2% |
| 145 | 317.5922 | 330.5552 | 12.9629 | 323.944 | ±2% |
| 287 | 93,108.96 | 96,909.3257 | 3,800.3657 | 94,971.1392 | ±2% |
| 288 | 96,909.3257 | 100,864.8084 | 3,955.4827 | 98,847.5123 | ±2% |
폭은 값이 커질수록 γ배씩 넓어지는데 상대오차는 모든 줄에서 같습니다. 이것이 로그 버킷의 전부입니다. 대표값을 2γⁱ/(γ+1)로 잡아야 양쪽 끝에서의 오차가 같아져 α 상한이 딱 맞습니다 — 산술 중앙으로 잡으면 아래쪽 끝에서 오차가 더 커집니다.
반대로, 칸 수를 먼저 정하면
γ = (max/min)^(1/칸수)로 두고 α = (γ−1)/(γ+1)을 되짚은 값입니다. 메모리 예산이 먼저 정해져 있을 때 어느 정도 정밀도를 기대할 수 있는지 볼 수 있습니다.
가장 작은 값 1은 0번 버킷, 가장 큰 값 100,000은 288번 버킷입니다. 번호가 음수여도 괜찮습니다 — 1보다 작은 값의 로그가 음수이기 때문이며, 배열에 담을 때는 최소 번호만큼 밀어 두면 됩니다.
사용 방법
- 1담을 값의 가장 작은 값과 가장 큰 값을 넣습니다. 지연시간이면 ms 단위로 두면 됩니다.
- 2보장하고 싶은 상대오차(α)를 넣습니다. 2%가 흔한 선택입니다.
- 3견줄 등간격 버킷의 폭을 넣으면 같은 범위에 몇 칸이 필요한지 나란히 보여 줍니다.
- 4필요한 칸 수와 메모리를 확인합니다.
- 5반대로 쓸 수 있는 칸 수가 정해져 있으면 아래에서 그때의 상대오차를 되짚을 수 있습니다.
자주 묻는 질문
등간격 버킷은 값이 여러 자릿수에 걸칠 때 칸 수와 정밀도를 동시에 잃기 때문입니다. 1ms 간격으로 100s까지 담으면 10만 칸이 필요한데도 1ms 언저리 오차가 ±50%입니다. 경계를 등비수열로 두면 289칸으로 모든 구간에서 상대오차 2%를 지킬 수 있습니다.
⌈log_γ(v)⌉입니다. γ = (1+α)/(1−α)이고 α가 보장 상대오차입니다. 그 버킷의 범위는 (γ^(i−1), γ^i]이며, 값이 1보다 작으면 번호가 음수가 됩니다 — 배열에 담을 때는 최소 번호만큼 밀어 두면 됩니다.
2γⁱ/(γ+1)로 잡아야 버킷 양쪽 끝에서의 상대오차가 정확히 같아지기 때문입니다. 산술 중앙으로 잡으면 아래쪽 끝에서 오차가 α를 넘습니다. 이 대표값에서 상한이 정확히 α = (γ−1)/(γ+1)이 됩니다.
log_γ(max/min)입니다. 범위가 백 배 넓어져도 칸은 로그만큼만 늘어납니다. 1ms~100s를 상대오차 2%로 담으면 289칸, 8바이트 카운터면 2.3KB 남짓입니다.
분위수로 나온 값이 참값의 ±2% 안에 있다는 뜻입니다. 값에 대한 보장이지 순위에 대한 보장이 아니므로, p99로 나온 값이 실제로 몇 번째 요청인지는 이 보장에 들어 있지 않습니다.
따로 세야 합니다. 로그를 취할 수 없기 때문입니다. 실제 구현에서는 0 근처를 위한 카운터를 하나 두고, 음수가 필요하면 부호별로 스케치를 따로 둡니다. 아주 작은 양수까지 담으려 하면 칸이 늘어나므로 하한을 정해 두는 편이 낫습니다.
같은 γ를 쓰면 같은 번호의 칸을 그냥 더하면 됩니다. 합친 결과도 여전히 상대오차 α를 지킵니다. 서버마다 p99를 따로 구해서 평균 내는 것과는 전혀 다르며, 그 방식은 틀린 답을 줍니다.
전송되지 않습니다. 계산은 모두 브라우저 안에서 이루어지고 넣은 값은 이 기기에만 남습니다.
알아두면 좋은 점
- 메모리는 「모든 칸이 다 쓰인다면」의 상한입니다. 실제로는 값이 나온 칸만 만들어 두는 구현이 많아 훨씬 적게 듭니다.
- 상대오차는 분위수 값에 대한 보장입니다. 순위(몇 번째인가)에 대한 보장이 아닙니다.
- 0과 음수는 이 방식으로 담을 수 없어 따로 세야 합니다.
- 카운터 자체의 크기와 인덱스 자료구조(해시맵·배열)의 부가 비용은 따로입니다.
함께 보면 좋은 도구
마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.