본문 바로가기
개발 이야기/Django

uwsgi processes, threads 값을 조정하여 서버 성능 향상하기

by _ppuing 2021. 1. 13.
반응형

uwsgi 실행을 위해 .ini 파일을 작성할 때, processes, threads 값을 조절하여 현재 서버가 요청을 동시에 얼마나 처리할지 결정할 수 있다. 기본적인 파일 예시는 아래와 같다. 이 값을 따로 만지지 않으면, 최저 사양으로 서버가 돌기 때문에, 코어 개수가 4대임에도 프로세스가 단 하나만 생성되어 동시 요청이 많이 들어오는 경우, 몇몇 요청은 TIMEOUT 에러를 받을 수 있다. 때문에, 서버의 사양에 맞춰서 적절한 프로세스, 스레드 개수를 설정하면 많은 동시 요청을 적절하게 대응하여 처리할 수 있다.

[uwsgi]
module = wsgi:app

master = true
processes = 8
threads = 16
enable-threads = true

socket = :5050
chmod-socket = 664
vacuum = true

die-on-term = true
pidfile = /var/run/uwsgi/my_server.pid

buffer-size = 65536

env = SERVER_NAME=dev
harakiri = 60

위 내용 중 이번 내용에 해당 되는 부분은 아래와 같다.

 

processes: # of CPU cores

threads: 1 process에서 사용할 thread 개수

enable-threads: 위 threads를 사용하기 위해 true로 설정 

 

나의 서버에서 지원 가능한 CPU 개수는 아래 명령어를 통해 확인 가능하다.

 

lscpu 명령어의 결과 예시

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             4
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 79
Stepping:              1
CPU MHz:               2199.998
BogoMIPS:              4399.99
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              25600K
NUMA node0 CPU(s):     0-3

위 서버를 보면 CPU가 4개인데, 나는 보통 CPU 개수의 두 배 정도로 값을 정한다. (물론 값을 점점 바꿔가면서 뭐가 제일 빠른지 보는 게 가장 좋다.) 왜냐면 CPU가 4개라고 프로세스 4개를 할당하면, 유휴 시간 동안에는 CPU가 노는 시간이 발생하는데, 프로세스를 8개로 설정하면 4개 프로세스를 처리하고 곧바로 다음 4개 프로세스 처리를 하기 때문에 CPU가 노는 시간이 발생하지 않는 것 같다. (4개로 설정했을 때보다 8개로 설정했을 때가 조금 더 성능이 좋았다.)

threads 같은 경우는 값을 조금씩 바꿔보면서 가장 빠른 값을 설정하면 된다. 나 같은 경우는 2, 4, 8 ,16 순서로 늘려가면서 적절한 값을 설정했다.

 

아래 코드를 통해 100개의 총 요청을 처리하기 위해 걸린 시간을 대강 체크해볼 수 있다. (하지만 이건 모든 요청이 끝난 시간을 보는 것이기 때문에 엄청 정확한 결과를 보는 것은 아니다. - (개별 요청에 대한 평균 response 시간을 계산하는 것이 가장 효율적이다.)

example.com 으로 동시 요청 보내는 테스트 코드

import requests
import threading
import time

def req():
    try:
        response = requests.get('https://example.com', verify=False)
        print response
    except:
        # import traceback
        # traceback.print_exc()
        pass
    
threads = []
tic = time.time()
for i in range(100):
    t = threading.Thread(target=req)
    t.start()
    threads.append(t)
    
for t in threads:
    t.join()

print 'tic toc', time.time() - tic

 

반응형

댓글