Как повысить скорость запросов в Gunicorn

#python #gunicorn #fastapi #uvicorn #aioredis

Вопрос:

Мы протестировали приложение fastAPI с помощью Guicorn с 20 сотрудниками, код для которого приведен ниже,

 import json
from typing import List, Dict
from async_lru import alru_cache
from fastapi import FastAPI
import aioredis

REDIS_HOST: str = "localhost"
app: FastAPI = FastAPI()

@alru_cache
async def get_redis() -> aioredis.Redis:
    """
    :return:
    """
    return await aioredis.create_redis_pool((REDIS_HOST, 6379), encoding='utf8')

@app.get('/redisConnection')
async def async_function():
    redis_conn: aioredis.Redis = await get_redis()
    return None

@app.get('/doOneRedisCall')
async def do_one_redis_call():
    redis_conn: aioredis.Redis = await get_redis()
    data: str = await redis_conn.get('random_key')
    return json.loads(data)

@app.get('/doMultipleRedisCall')
async def do_one_redis_call():
    redis: aioredis.Redis = await get_redis()
    redis_key_list: List[str] = ['random_key_1', 'random_key_2', 'random_key_3', 'random_key_4']
    response: List[Dict] = []
    for key in redis_key_list:  # making 4 get calls to redis
        data: str = await redis.get(key)
        response.append(json.loads(data))
    return response
 

мы запускаем это приложение, используя следующую команду cmd,

gunicorn -w 20 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:80 main:app

Системные
характеристики: ПРОЦЕССОР : 8 ядер
ОЗУ : 64 ГБ
Частота процессора : 2700,516

для /redisConnection API машина могла принимать нагрузку до 7000 запросов в секунду
для /doOneRedisCall API машина могла принимать нагрузку до 4700 запросов в секунду
для /doMultipleRedisCall API машина могла принимать нагрузку до 1700 запросов в секунду

Чем больше вызовов redis выполняется, тем меньше скорость запросов может обрабатываться машиной, какие параметры в Gunicorn мы могли бы изменить, чтобы он мог обрабатывать большую скорость запросов.?
Мы попытались увеличить
число рабочих подключений с 1000(по умолчанию) до 10000
, поддерживать — 2(по умолчанию) до 10 секунд
, отставание — 2048(по умолчанию) до 100000
.Скорость запросов не улучшилась. Есть ли что-нибудь, чего мне здесь не хватает?

Комментарии:

1. Проанализировали ли вы свою программу, чтобы увидеть, где она проводит большую часть своего времени? Если вы этого не сделали, сделайте это в первую очередь. Затем вы можете начать оптимизировать эти узкие места. (Тем не менее, я не уверен, что стоит оптимизировать такую игрушечную программу, как эта.)

2. Также: звучит так, как будто doMultipleRedisCall следует использовать MGET для получения нескольких значений.

3. И теперь, когда я этим занялся: существуют более быстрые библиотеки JSON, чем встроенные json ; см., например orjson .