성능 수치는 하나의 숫자보다 같은 관측 경계에서 측정한 흐름입니다. 완료 처리율, 체류 시간, 대기 길이, 실패와 timeout을 같은 workload와 시간 창에 놓아야 포화로 인한 지연 증가와 빠른 거절로 인한 평균 하락을 구분할 수 있습니다. 이 노트는 그 측정 경계를 수학식과 함께 고정합니다.
동시 수용량과 적시 완료 처리량
동시성을 늘리면 I/O 대기를 겹쳐 처리량을 높일 수 있습니다. 하지만 DB가 포화된 뒤에는 실행 능력보다 풀 대기·메모리·timeout만 늘 수 있습니다. throughput은 단위 시간의 완료량이고 latency는 한 요청의 체류 시간입니다. 여러 요청이 겹치는 시스템에서 둘을 단순 역수로 볼 수 없습니다.
성공·실패·거절·timeout의 수와 지연을 나눕니다. 빠른 오류가 늘어 평균이 낮아지거나 timeout 표본을 빼 p99가 좋아졌다면 사용자 작업이 개선됐다는 증거가 아닙니다. 용량은 지정한 workload에서 지연·오류 SLO를 만족하며 지속 가능한 성공 처리율로 정합니다.
Little의 법칙과 동일 경계의 평균량
안정된 관측에서 평균 체류 수 L=λW입니다. 초당 100개가 평균 0.2초 머무르면 평균 20개입니다. 전체 HTTP 체류를 쓰면 queue와 실행을 포함한 요청 수이고, DB 연결 보유만 쓰면 그 경계의 평균 점유 수입니다. 서로 다른 시간 창·분모·경계를 곱하지 않습니다.
| 경계 | λ | W | L의 의미 |
|---|---|---|---|
| HTTP 전체 | 그 경계의 처리율 | 대기+실행+응답 | 진행·대기 요청 평균 |
| DB 연결 보유 | 연결 사용 완료율 | 획득 후 반환까지 | 빌린 연결 평균 |
| 작업 실행 | 실행 완료율 | 실제 active 시간 | 활성 작업 평균 |
평균 20이라는 결과가 pool 20이면 burst와 p99를 만족한다는 뜻은 아닙니다. 지속 적체에서는 정상 상태 가정이 맞지 않을 수 있어 수락률·완료율·유한 queue를 먼저 봅니다. 유입 제한·실제 종결에 묶인 permit·대기 바이트 상한으로 overload를 다룹니다.
서버별 P99 평균의 한계와 histogram 기반 전체 분위수
A 서버의 10ms 요청 1000개와 B 서버의 1000ms 요청 1개를 합친다고 합시다. 정렬한 전체 표본에서 p99 위치의 값을 택하는 nearest-rank 방식으로는 전체 p99가 10ms이지만, 서버별 p99 숫자만 평균하면 505ms가 됩니다. 요청 수로 가중한 p99 평균도 일반적으로 전체 분위수를 복원하지 못하는데, 각 서버의 원래 분포 정보가 이미 사라졌기 때문입니다.
서버별 p99 숫자를 다시 평균내지 말고, 같은 단위·경계·시간 창에서 관측한 histogram의 bucket count를 합친 뒤 그 누적 분포에서 분위수를 추정합니다. classic histogram은 bucket별 count를 누적해 저장하는지 비누적으로 저장하는지 구분해야 하고, native histogram·summary는 병합 방식과 오차 계약이 다를 수 있으므로 사용 중인 저장소의 규칙을 확인합니다.
bucket이 넓을수록 p99 추정 오차가 커지므로 SLO 주변에 필요한 해상도와 저장 비용을 맞추고, 전체 집계 아래 지역·route별 실패가 숨지 않는지도 봅니다.
그림을 글로 읽기
- A의 지연 bucket·count
- B의 같은 경계 bucket·count
- 단위·창을 맞춰 count 합산
- 전체 분포의 p99 추정
- A의 지연 bucket·count → 단위·창을 맞춰 count 합산: 요청 수 보존
- B의 같은 경계 bucket·count → 단위·창을 맞춰 count 합산: 요청 수 보존
- 단위·창을 맞춰 count 합산 → 전체 분포의 p99 추정: 분포에서 계산
p99는 모든 요청의 상한이 아니고 표본·quantile 알고리즘에 따라 흔들립니다. 소수 요청의 tail을 과도하게 정밀한 숫자로 해석하지 않습니다. timeout의 실제 끝을 모르면 관측된 하한·오류와 실제 작업 종결을 구분합니다.
Amdahl의 고정 작업 병렬화 상한
고정 작업의 순차 비율 s, 병렬도 p의 이상적 speedup은 1/(s+(1-s)/p)입니다. s=0.2면 p=2에서 약 1.67배, p=4에서 2.5배, 무한 병렬에서도 5배가 한계입니다. 추가 통신·합치기·lock·memory bandwidth 비용이 없다는 모형이므로 실제는 더 작거나 오히려 느려질 수 있습니다.
고정 입력 하나의 latency를 줄이는 strong scaling과 더 큰 입력을 같은 시간에 처리하는 문제를 구분합니다. worker를 늘리기 전에 CPU·off-CPU·불균형·NUMA·coherence를 확인하고 병목을 고친 뒤 다시 측정합니다. 코어 숫자가 DB·네트워크 용량을 늘리지는 않습니다.
요청 혼합에 따른 TPS와 작업량 비교 기준
작은 조회 1000건/초와 큰 export 100건/초를 단순 TPS로 우열 비교하지 않습니다. 유형별 처리량·성공·지연·CPU·I/O·바이트를 기록하고 운영 혼합을 고정한 대조를 둡니다. 가중 처리량을 쓰면 기준 비용·가중치 버전을 명시합니다.
예를 들어 기준 작업 단위로 조회=1, 집계=10이면 900조회+10집계는 1000단위/초입니다. 이는 선택한 비용 척도이지 CPU·메모리·DB를 동시에 정확히 대표하는 물리량은 아닙니다. 실패·재시도·보상 비용도 별도 포함하고 가중 수치로 작은 tenant의 지연을 숨기지 않습니다.
부하 시험은 낮은 입력률에서 시작해 성공 처리율·p99·queue age를 함께 기록하고, timeout과 거절을 성공 표본에서 숨기지 마십시오. 예상 결과는 포화 전에는 처리율이 입력률을 따라가지만 포화 뒤에는 성공 처리율이 평평해지고 p99와 queue age가 커지는 것입니다. 서버별 p99 평균 대신 동일 bucket count를 합쳐 계산한 값만 전체 분포의 근사로 사용합니다.
포화 전후·회복 구간의 동일 조건 비교
입력률·동시성을 단계적으로 바꿔 성공 처리율이 평평해지고 p99·queue age가 커지는 지점을 찾습니다. 그보다 여유 있는 운영 범위를 정하고 burst 후 회복도 확인합니다. 위 숫자는 수학적 예제이며 실제 서비스 capacity 벤치마크를 수행한 결과가 아닙니다.