【问题标题】:Redis publishing when no subscriber没有订阅者时的 Redis 发布
【发布时间】:2012-08-13 09:33:13
【问题描述】:

在 Redis pub/sub 中,如果在没有订阅者的情况下发布某些内容,则数据会丢失。

我想要的是在订阅者订阅时向发布者发出通知。

一种方法是保持循环发布,并在发布者找到至少一个订阅者时打破循环。但我不认为这是一个好方法。 (我也不能保持指数回退)。

while(1) {
    $numOfSubscriber = $redis->publish($channel1, $encodePublish);
    if($numOfSubscriber > 0)
        break;
}

有没有更好的方法来解决同样的问题?

我正在使用 Predis。

【问题讨论】:

    标签: redis publish-subscribe


    【解决方案1】:

    除非您详细解释您的用例,否则很难具体说明,但如果一个订阅者收到任何消息就足够了,您可以使用 redis 列表实现一个队列并将所有消息存储在那里,同时发布。伪代码:

    出版商:

    # Persist message in a queue
    lpush channel1.queue message
    # Publish message to any connected subscriber
    publish channel1 message
    

    订阅者:

    # Subscribe to channel1
    subscribe channel1
    # Process any persisted messages
    brpop channel1.queue
    

    编辑:另一种解决方案,发布者仅在没有订阅者的情况下存储消息:

    出版商:

    subscribers = publish channel1 message
    if subscribers == 0
      lpush channel1.queue message
    

    订阅者:

    # handle stored messages
    while(message = rpop channel1.queue)
      # process message
    
    # subscribe for new messages
    subscribe channel1
    

    【讨论】:

    • 我不想真正存储任何值,在我的应用程序中,我关心的是当发布者发布时应该有一些订阅者来捕获该消息而不将发布者置于循环中。如果订阅者在发布者之后开始,那么它可能会错过来自发布者的消息。
    • 是的,这就是为什么您也可以存储它们,然后让订阅者弹出它们。或者只有在没有订阅者的情况下才能推送它们。但正如我所说,如果没有关于您的案例的更多信息,很难给出直截了当的建议。
    • 我的用例是:我想向其中一名工作人员发送确认以开始工作并将一些数据推送到队列,如果其他工作人员(发送确认的人)准备好。所以它发送 ack 并且接收它的工作人员开始推送数据。这样解释更好吗?我试图解释我的用例。一种解决方案可能是保留一组 pub/sub 以进行控制。