[멀티 프로세스][cpu server] 단일 프로세스 → 멀티 프로세스 (병목 개선 및 트러블 슈팅) - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
1. 개요
- 단일 프로세스 구조 → 다중 프로세스: 속도 향상 정도 분석
- GIL의 영향 없이 요청을 병렬적으로 처리하여 속도가 향상될 것으로 예상
2. 트러블 슈팅
-
k6 script에서 iteration 간 랜덤 sleep을 위해 randomIntBetween 이용 시, 모듈 잘못 import
-
임베딩 성공 시 카테고리 분류하도록 & 서버 keepalive와 k6의 sleep 완전히 겹쳐 connection reset
3. 속도 측정 (gpu 서버는 단일 프로세스 상태)
a. cpu 서버 단일 프로세스
b. cpu 서버 멀티 프로세스
c. 분석: 지연 증가
- 멀티 프로세스 도입 후 18s → 37s로 요청 처리 시간 늘어남
가. 가설: 레디스 노드가 한 개라 병렬 요청량이 많아서 병목이 발생했을 것이다 - 거짓
1회 요청
-----[Redis Set Start]-----
[Redis SET] key='img549.jpg' succeeded, took 0.0011 seconds, TTL=300
-----[Redis Set Start]-----
[Redis SET] key='img550.jpg' succeeded, took 0.0012 seconds, TTL=300
2025-06-09 12:00:53.461 | INFO | app.utils.logging_decorator:async_wrapper:61 - embed_controller 함수 성공
2025-06-09 12:00:53.461 | INFO | fastapi.routing:app:301 - embed 함수 성공
2025-06-09 12:01:01.451 | INFO | fastapi.routing:app:301 - categorize 함수 시작
2025-06-09 12:01:01.451 | INFO | app.utils.logging_decorator:async_wrapper:61 - categorize_controller 함수 시작
categorize_controller 임베딩 로드 전
[Redis BULK GET] 50 keys took 0.0347 seconds
categorize_controller 임베딩 로드 후
- 단일 요청에서 Redis get, set 시간을 기준으로 다중 요청 시에 늘어나는지 확인
- get: 약 0.001s
- set: 약 0,035s
- 다중 요청 시에도 Redis get, set 처리 시간은 늘지 않음 → Redis는 병목 원인이 아님
나. 가설: gpu 서버 처리 시간이 밀려서 병목이 발생했을 것이다.
- 단일 프로세스 구조 → 멀티 프로세스 구조
다중 요청 상황에서 요청 1건 당 gpu 서버 처리 시간: 1.01s → 2.7s
- 건당 1~2초 가량 지연 증가 (병렬적으로 많은 요청 처리 → 컨텍스트 스위칭 증가 예상)
- 초당 가상 유저 20명이기 때문에 늦게 들어온 요청일수록 처리 시간이 선형적으로 증가하여 k6 기준 지연 시간이 18s → 37s로 늘은 것으로 예상
다. 검증1: cpu → gpu 서버 병렬 요청으로 gpu 서버의 스레드 수가 늘어 컨텍스트 스위칭이 심화되었다.
watch -n 1 'ps -eLf | wc -l'
- 매 초마다 전체 시스템의 스레드 수 총합 출력
단일 프로세스
gpu | cpu | |
---|---|---|
요청 전 | 244 | 186 |
후 | 평균 261-275 (최대 305) | 193-202 |
다중 프로세스
gpu | cpu | |
---|---|---|
요청 전 | 245 | 192 |
후 | 평균 262-292 (최대 342) | 202 |
- gpu 서버에서 요청이 처리될 때, 기존 대비 평균적으로 더 많은 스레드가 생성되는 것 확인
- gpu 서버 단일 프로세스 환경에서는 스레드 간 컨텍스트 스위칭이 심화되어 병목이 발생함(동시성의 한계) → 개선 방향: gpu 서버를 멀티 프로세스로 수정하여 GIL의 영향 없이 병렬적으로 요청 처리