[멀티 프로세스][cpu server] 단일 프로세스 → 멀티 프로세스 (병목 개선 및 트러블 슈팅) - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

1. 개요

  • 단일 프로세스 구조 → 다중 프로세스: 속도 향상 정도 분석
  • GIL의 영향 없이 요청을 병렬적으로 처리하여 속도가 향상될 것으로 예상

2. 트러블 슈팅

3. 속도 측정 (gpu 서버는 단일 프로세스 상태)

a. cpu 서버 단일 프로세스

멀티cpuimage

b. cpu 서버 멀티 프로세스

멀티cpuimage 1

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의 영향 없이 병렬적으로 요청 처리