Embedding 세마포어 설정 후 테스트 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
1. 테스트 목적
a. 가정
- Embedding은 CPU-bound 작업으로, 많은 스레드를 사용할 경우 전체 리소스를 잠식한다.
- Embedding이 많은 스레드를 점유할 경우, 비교적 가벼운 후속 작업(categories, quality 등)의 대기시간이 길어진다
- 따라서 embedding 동시 실행 개수를 제한하면 후속 작업들이 지연 없이 처리되어 전체 처리 시간이 줄어들 것이다.
b. 예상 결과
- Embedding 자체 속도는 약간 저하될 수 있음
- 하지만 후속 작업들이 안정적으로 병렬 수행되면서 전체 요청 처리 시간은 단축될 것으로 기대
2. 테스트 설계
a. 도구
- 부하 테스트 도구:
k6
- 백엔드 서버: FastAPI
- 실행 환경: CPU 서버,
max_workers
고정 - 지표 수집: avg / p95 / max + http_req_failed 여부
b. 방식
- 실험 1:
max_workers=8
, embedding에 세마포어 미적용 - 실험 2:
max_workers=8
, embedding에 세마포어(max_concurrency=4
) 적용 - 각 실험에 대해 VUs(동시 사용자)를 10, 15, 20, 25, 30까지 순차적으로 증가시키며 테스트 진행
- 비교 지표:
- 각 작업별 처리 시간 (embedding / categories / duplicates / quality / score)
- 전체 요청 처리 시간 (total_duration)
- 실패율 (http_req_failed)
- iteration_duration을 통해 실질적 대기 시간 확인
3. 테스트 결과
- max_workers = 8
-
세마포어 도입 전
VUs Embedding (avg / p95 / max) Categories (avg / p95 / max) Duplicates (avg / p95 / max) Quality (avg / p95 / max) Score (avg / p95 / max) Total (avg / p95 / max) http_req_failed 10 4.30s / 5.10s / 5.10s 193ms / 347ms / 360ms 192ms / 347ms / 351ms 191ms / 360ms / 376ms 98ms / 193ms / 202ms 4.97s / 5.23s / 5.24s 0.00% 15 5.39s / 7.21s / 7.30s 1.13s / 2.27s / 2.27s 1.14s / 2.31s / 2.33s 1.13s / 2.31s / 2.31s 347ms / 934ms / 1.01s 9.15s / 11.11s / 11.11s 0.00% 20 6.68s / 9.67s / 9.68s 2.38s / 4.64s / 4.76s 2.38s / 4.63s / 4.75s 2.38s / 4.65s / 4.76s 409ms / 992ms / 1.11s 14.23s / 18.55s / 18.83s 0.00% 25 8.00s / 11.87s / 12.16s 3.66s / 7.07s / 7.21s 3.65s / 7.13s / 7.18s 3.66s / 7.08s / 7.20s 323ms / 886ms / 997ms 19.29s / 25.99s / 26.17s 0.00% 30 9.42s / 14.48s / 14.62s 4.74s / 8.84s / 9.37s 4.73s / 8.88s / 9.38s 4.73s / 8.85s / 9.37s 465ms / 1.72s / 1.76s 24.09s / 32.10s / 33.36s 0.00% -
세마포어 도입 후
VUs Embedding (avg / p95 / max) Categories (avg / p95 / max) Duplicates (avg / p95 / max) Quality (avg / p95 / max) Score (avg / p95 / max) Total (avg / p95 / max) http_req_failed 10 3.51s / 5.11s / 5.15s 157ms / 286ms / 290ms 130ms / 256ms / 258ms 138ms / 263ms / 268ms 85ms / 144ms / 148ms 4.02s / 5.31s / 5.35s 0.00% 15 4.56s / 7.23s / 7.33s 172ms / 303ms / 332ms 154ms / 258ms / 259ms 174ms / 295ms / 330ms 108ms / 181ms / 184ms 5.17s / 7.43s / 7.52s 0.00% 20 5.82s / 9.53s / 9.74s 158ms / 295ms / 318ms 152ms / 260ms / 320ms 157ms / 280ms / 300ms 111ms / 171ms / 199ms 6.40s / 9.74s / 9.93s 0.00% 25 7.00s / 11.61s / 12.44s 194ms / 305ms / 330ms 190ms / 280ms / 296ms 200ms / 305ms / 331ms 121ms / 251ms / 260ms 7.70s / 11.82s / 12.65s 0.00% 30 8.25s / 14.21s / 14.57s 193ms / 289ms / 316ms 179ms / 263ms / 285ms 187ms / 260ms / 273ms 124ms / 234ms / 264ms 8.93s / 14.44s / 14.78s 0.00%
-
- max_workers = 12
-
세마포어 도입 전
VUs Embedding (avg / p95 / max) Categories (avg / p95 / max) Duplicates (avg / p95 / max) Quality (avg / p95 / max) Score (avg / p95 / max) Total (avg / p95 / max) http_req_failed 10 4.88s / 5.12s / 5.12s 219ms / 398ms / 412ms 209ms / 393ms / 402ms 191ms / 403ms / 421ms 94ms / 228ms / 248ms 5.59s / 5.89s / 5.92s 0.00% 15 6.25s / 7.41s / 7.49s 618ms / 1.62s / 1.67s 592ms / 1.57s / 1.58s 618ms / 1.59s / 1.67s 225ms / 504ms / 507ms 8.30s / 10.02s / 10.08s 0.00% 20 7.52s / 9.80s / 9.81s 1.08s / 2.32s / 2.33s 1.06s / 2.28s / 2.29s 1.09s / 2.33s / 2.35s 511ms / 1.17s / 1.26s 11.26s / 13.37s / 13.44s 0.00% 25 8.88s / 12.07s / 12.37s 2.79s / 5.89s / 6.28s 2.80s / 5.84s / 5.85s 2.84s / 5.87s / 6.16s 319ms / 962ms / 1.03s 17.63s / 23.52s / 23.68s 0.00% 30 10.33s / 14.72s / 14.75s 3.82s / 7.53s / 7.57s 3.80s / 7.60s / 7.72s 3.82s / 7.56s / 7.62s 577ms / 1.87s / 1.89s 22.35s / 29.69s / 29.91s 0.00% -
세마포어 도입 후
VUs Embedding (avg / p95 / max) Categories (avg / p95 / max) Duplicates (avg / p95 / max) Quality (avg / p95 / max) Score (avg / p95 / max) Total (avg / p95 / max) http_req_failed 10 3.59s / 5.38s / 5.42s 151ms / 255ms / 267ms 167ms / 241ms / 241ms 179ms / 270ms / 275ms 97ms / 229ms / 248ms 4.18s / 5.58s / 5.61s 0.00% 15 4.63s / 7.44s / 7.44s 195ms / 302ms / 302ms 192ms / 302ms / 303ms 201ms / 301ms / 305ms 94ms / 138ms / 150ms 5.31s / 7.69s / 7.69s 0.00% 20 5.80s / 9.61s / 9.63s 189ms / 271ms / 277ms 178ms / 282ms / 288ms 181ms / 285ms / 300ms 126ms / 226ms / 248ms 6.47s / 9.84s / 9.87s 0.00% 25 7.00s / 11.67s / 12.40s 176ms / 298ms / 306ms 158ms / 268ms / 285ms 183ms / 284ms / 319ms 107ms / 177ms / 242ms 7.63s / 11.88s / 12.60s 0.00% 30 8.24s / 14.16s / 14.64s 188ms / 277ms / 283ms 175ms / 262ms / 311ms 188ms / 280ms / 311ms 116ms / 221ms / 262ms 8.91s / 14.38s / 14.85s 0.00%
-
max_workers = 8
기준)
a. 세마포어 설정 전후 시간 변화율(-
변화율(%) = (세마포어 설정 후 시간 - 설정 전 시간) / 세마포어 설정 전 시간 * 100
-
+%
는 느려짐 (🔴),-%
는 개선 (🔵)을 의미VUs Embedding (avg/p95/max) Categories (avg/p95/max) Duplicates (avg/p95/max) Quality (avg/p95/max) Score (avg/p95/max) Total (avg/p95/max) 10 🔵 −18.4%/🔴 +0.2%/🔴 +1.0% 🔵 −18.7%/🔵 −17.6%/🔵 −19.4% 🔵 −32.3%/🔵 −26.2%/🔵 −26.5% 🔵 −27.7%/🔵 −4.5%/🔵 −28.7% 🔵 −13.3%/🔵 −26.9%/🔵 −28.7% 🔵 −19.1%/🔴 +1.0%/🔴 +2.1% 15 🔵 −15.4%/🔴 +0.3%/🔴 +0.4% 🔵 −84.8%/🔵 −86.6%/🔵 −85.4% 🔵 −86.5%/🔵 −88.8%/🔵 −88.8% 🔵 −84.6%/🔵 −87.1%/🔵 −85.7% 🔵 −68.9%/🔵 −87.1%/🔵 −85.7% 🔵 −43.5%/🔵 −33.7%/🔵 −32.3% 20 🔵 −12.9%/🔵 −1.5%/🔴 +0.6% 🔵 −93.4%/🔵 −93.2%/🔵 −93.1% 🔵 −93.6%/🔵 −93.3%/🔵 −93.1% 🔵 −93.4%/🔵 −94.0%/🔵 −93.5% 🔵 −72.9%/🔵 −94.0%/🔵 −93.5% 🔵 −55.0%/🔵 −48.0%/🔵 −47.0% 25 🔵 −12.4%/🔵 −2.0%/🔴 +4.8% 🔵 −94.5%/🔵 −95.8%/🔵 −95.7% 🔵 −94.6%/🔵 −96.1%/🔵 −96.1% 🔵 −94.3%/🔵 −95.7%/🔵 −95.6% 🔵 −62.5%/🔵 −95.7%/🔵 −95.6% 🔵 −59.6%/🔵 −54.6%/🔵 −54.5% 30 🔵 −12.5%/🔵 −4.5%/🔴 +0.6% 🔵 −96.3%/🔵 −96.7%/🔵 −96.4% 🔵 −96.5%/🔵 −97.0%/🔵 −96.8% 🔵 −96.3%/🔵 −97.0%/🔵 −96.5% 🔵 −75.1%/🔵 −97.0%/🔵 −96.5% 🔵 −63.0%/🔵 −56.3%/🔵 −55.0% -
Embedding 작업 자체의 평균 시간은 약 12~18% 정도로 개선
→ 임베딩 작업이 코어 수 이상으로 돌아가게 되면 오히려 느려질 수 있다는 것을 확인
-
Max나 p95는 오히려 증가하는 경우도 발생
→ Semaphore 경쟁에 따라 밀리는 embedding 작업이 존재한다는 것을 알 수 있음
→ Queue를 도입하면 해결할 수 있지 않을까 생각
-
반면, categories / quality / duplicates / score 등 나머지 작업들은 90% 가까이 응답시간이 감소
- 예:
VUs = 20
일 때 categories의 p95가 4.60s → 0.31s로 93.2% 감소
- 예:
-
이에 따라 전체 처리 시간(
total
)도 최대 63%까지 단축됨:VUs = 30
: 총 처리 시간 평균(avg) 기준 24.09s → 8.91s (−63%)
4. 결과 요약
- 세마포어 설정은 embedding의 연산 독점을 막고 다른 작업의 병렬 처리 여유를 확보해줌
- 전체 응답 성능을 가장 크게 개선하는 주요 요인이 되었음
- 특히 VU 수가 많아질수록 성능 개선 효과가 극대화됨