Как установить строгий тайм-аут для операции кластера Redis в Python? - PullRequest
1 голос
/ 29 апреля 2020

Я работал над проектом Python / Django и использую uWSGI в качестве веб-сервера.

В процессе ответа на запрос некоторые данные извлекаются из кластера Redis с помощью redis- р-кластер. К сожалению, каждый раз, когда в кластере возникает проблема, и она не отвечает, из-за того, что все работники uWSGI заняты, вся система выходит из строя.

Поэтому я решил установить таймаут для операций кластера и предотвратить они занимают больше, чем допустимое количество (10 мс в моем случае). До сих пор я пробовал многопоточность, которая полностью потерпела неудачу в недавнем кластерном инциденте.

Также я пробовал asyncio. Были некоторые рекомендации по использованию run_in_executor, которые я использовал, и, тем не менее, кажется, что время ожидания не слишком сильно. Наконец, есть aredis, который предоставляет асин * c версию StrictRedisCluster из redis-py-cluster. Я использовал это, но он потреблял слишком много ресурсов процессора и памяти, поэтому я немедленно восстановил его.

Вот код:

import asyncio
from concurrent.futures.thread import ThreadPoolExecutor
from rediscluster import StrictRedisCluster
from aredis import StrictRedisCluster as AsyncStrictRedisCluster


loop = asyncio.get_event_loop()
redis_cluster = StrictRedisCluster.from_url(REDIS_CLUSTER_URL)
async_redis_cluster = AsyncStrictRedisCluster.from_url(REDIS_CLUSTER_URL)


async def operation1(key):
    with ThreadPoolExecutor() as pool:
        return await asyncio.wait_for(loop.run_in_executor(pool, redis_cluster.get, key), timeout=0.01)


async def operation2(key):
    return await asyncio.wait_for(async_redis_cluster.get(key), timeout=0.01)


def execute_operation1(key):
    try:
        return loop.run_until_complete(operation1(key))
    except asyncio.TimeoutError:
        pass


def execute_operation2(key):
    try:
        return loop.run_until_complete(operation2(key))
    except asyncio.TimeoutError:
        pass


res = execute_operation1('some_key')  # This one sometimes takes more than 10 ms in both success and timeout states
also_res = execute_operation2('some_key')  # This one abnormally consumes CPU and memory in production server

Я что-то не так делаю? Я был бы очень признателен, если бы кто-то мог сказать мне, если есть какой-либо способ сделать это должным образом, или я просто трачу свое время.

Кстати, я впервые задаю вопрос, поэтому я Я прошу прощения за любые ошибки, которые я, возможно, сделал и для моего бедного Энгли sh.

...