在密钥存在之前阻止redis

2024-10-04 09:18:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚接触Redis,想知道是否有一种方法可以awaitget通过它的键对一个值进行awaitget直到该键存在。最小代码:

async def handler():
    data = await self._fetch(key)

async def _fetch(key):
    return self.redis_connection.get(key)

如您所知,如果这样的key不存在,它returnNone。但由于在我的项目中,set对redis的键-值对发生在另一个应用程序中,所以我希望redis连接get方法阻塞,直到key存在。 这样的期望甚至有效吗?在


Tags: 方法key代码selfredisdatagetasync
3条回答

除了@Itamar Haber提到的键空间通知方法,另一个解决方案是对LIST的阻塞操作。在

  1. handler方法对空的LIST:BRPOP notify-list timeout调用BRPOP,并阻塞直到{}不为空。在
  2. 另一个应用程序像往常一样完成键值对的设置后,将该值推送到LIST上:SET key value; LPUSH notify-list value。在
  3. handler使用所需的值从阻塞操作中唤醒,notify-list将被Redis自动销毁。在

此解决方案的优点是不需要对handler方法进行过多修改(使用键空间通知解决方案,您需要注册一个回调函数)。缺点是您必须依赖另一个应用程序的通知(使用keystpace通知解决方案,Redis会自动发出通知)。在

如果不在客户机上实现某种类型的池redis GET,就不可能完成您要做的事情。在这种情况下,你的客户必须做如下事情:

async def _fetch(key):
    val = self.redis_connection.get(key)
    while val is None:
       # Sleep and retry here
       asyncio.sleep(1)  
       val = self.redis_connection.get(key)
    return val

不过,我会要求你彻底地重新考虑你在这个问题上使用的模式。 在我看来,你需要做的是像Pub/Subhttps://redis.io/topics/pubsub这样的事情。在

因此,执行设置的应用程序成为发布者,而执行获取并等待密钥可用的应用程序成为订阅服务器。在

我对此做了一些研究,看起来你可以用asyncio\u redis来做:

希望这有帮助。在

最接近此行为的方法是启用keyspace notifications并订阅相关通道(可能是通过模式)。在

但是请注意,通知依赖于PubSub,它不能保证传递消息(最多一次是语义)。在

相关问题 更多 >