redis阻塞直到密钥存在

时间:2017-03-04 14:48:41

标签: python asynchronous redis python-asyncio

我是Redis的新手,并且想知道是否有办法能够{Key}密钥存在之前await get一个值。最小代码:

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

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

如您所知,如果此类key不存在,则returnNone。但是因为在我的项目中,set密钥值对redis发生在另一个应用程序中,我希望redis_connection get方法阻止直到存在的密钥。 这样的期望是否有效?

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

如果不在客户端上实现某种类型的 redis GET ,就无法做您想做的事情。在这种情况下,您的客户必须执行以下操作:

//<<DEBUG 2>>

但是,我会要求您完全重新考虑您正在使用此模式的模式。 在我看来,你需要做什么来做Pub / Sub https://redis.io/topics/pubsub

执行 SET 的应用程序成为发布者,执行 GET 并等待密钥可用的应用程序成为订阅者。

我对此做了一些研究,看起来你可以用asyncio_redis做到这一点:

希望这会有所帮助。

答案 2 :(得分:1)

除了@Itamar Haber提到的密钥空间通知方法之外,另一个解决方案是LIST上的阻止操作。

  1. handler方法在空BRPOPLIST上调用BRPOP notify-list timeout,并阻止notify-list非空。
  2. 其他应用程序在照常完成设置键值对后将值推送到LISTSET key value; LPUSH notify-list value
  3. handler使用您想要的值从阻止操作中唤醒,Redis会自动销毁notify-list
  4. 此解决方案的优点是您不需要过多地修改handler方法(使用键空间通知解决方案,您需要注册回调函数)。虽然缺点是您必须依赖另一个应用程序的通知(使用密钥空间通知解决方案,Redis会自动执行通知)。

答案 3 :(得分:1)

Redis 5.0之后,有内置的流支持阻塞读取。以下是带有redis-py的示例代码。

#add value to my_stream
redis.xadd('my_stream',{'key':'str_value'})

#read from beginning of stream
last_id='0'

#blocking read until there is value
last_stream_item = redis.xread({"my_stream":last_id},block=0) 

#update last_id
last_id = last_stream_item[0][1][0][0]

#wait for next value to arrive on stream 
last_stream_item = redis.xread({"my_stream":last_id},block=0)