如何在Python中设置Redis集群操作的严格超时?

如何在Python中设置Redis集群操作的严格超时?,python,python-asyncio,redis-cluster,Python,Python Asyncio,Redis Cluster,我一直在从事Python/Django项目,我使用uWSGI作为我的web服务器 在响应请求的过程中,使用Redis py cluster从Redis集群检索一些数据。不幸的是,每当集群中出现问题并且没有响应时,由于所有uWSGI工作人员都很忙,整个系统就会崩溃 因此,我决定在集群操作上设置一个超时,并防止它们花费的时间超过可接受的时间(在我的例子中是10毫秒)。到目前为止,我已经尝试了多线程,但在最近的集群事件中完全失败了 我也尝试过asyncio。有一些关于使用我使用的run_in_exec

我一直在从事Python/Django项目,我使用uWSGI作为我的web服务器

在响应请求的过程中,使用Redis py cluster从Redis集群检索一些数据。不幸的是,每当集群中出现问题并且没有响应时,由于所有uWSGI工作人员都很忙,整个系统就会崩溃

因此,我决定在集群操作上设置一个超时,并防止它们花费的时间超过可接受的时间(在我的例子中是10毫秒)。到目前为止,我已经尝试了多线程,但在最近的集群事件中完全失败了

我也尝试过asyncio。有一些关于使用我使用的run_in_executor的建议,尽管如此,它似乎不太尊重超时。最后还有aredis,它从redis py cluster提供了StrictRedisCluster的异步版本。我使用了它,但它不正常地消耗CPU和内存,所以我立即恢复了它

下面是一些代码:

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
我做错什么了吗? 如果有人能告诉我是否有什么方法可以做到这一点,或者我只是在浪费时间,我将不胜感激


顺便说一句,这是我第一次问问题,因此我为我可能犯的任何错误以及我糟糕的英语感到抱歉。

您可能应该添加服务器代码,以及如何运行它,否则可能很难理解您的问题。现在我建议只从异步代码开始(没有线程)。使代码尽可能简单,并尝试重现您的问题。代码中不应该包含的另一件事是自己启动异步任务(但我猜在实际代码中您不应该)。服务器应该为您运行任务(即,您的代码不应该与事件循环有任何交互,例如,不
循环。运行直到\u完成(…)
)。请确保您使用此引用作为起点:。我不知道uWSGI,所以我现在还不知道,但也许你可以尝试更简单的方法(像或任何其他面向ASGI的服务器)。你可能应该添加服务器的代码,以及如何运行它,否则可能很难理解你的问题。现在我建议只从异步代码开始(没有线程)。使代码尽可能简单,并尝试重现您的问题。代码中不应该包含的另一件事是自己启动异步任务(但我猜在实际代码中您不应该)。服务器应该为您运行任务(即,您的代码不应该与事件循环有任何交互,例如,不
循环。运行直到\u完成(…)
)。请确保您使用此引用作为起点:。我不知道uWSGI,所以我现在还不知道,但也许你可以尝试更简单的方法(像或任何其他面向ASGI的服务器)。