今天在使用StackExchange Redis客户端时。我想要使用BRPOP,但是我发现StackExchange Redis并没有提供API,没办法只好找资料看文档了。
原来StackExchange Redis使用的是Multiplexing(多路复用),也就是说它只跟redis server维持单个连接。当有并发请求时,它会自动使用管道(pipeline)发送每个请求,每个请求都需要等待直到先前的请求执行完毕。基于这个原因,StackExchange Redis不提供BRPOP/BLPOP相应的api, 因为这两个操作很有可能会阻塞整个Mulitplexer。
那么,有什么方法来实现BRPOP/BLPOP操作呢。文档中给出了答案,使用pub/sub:
sub.Subscribe(channel, () => { string work = db.ListRightPop(key); if (work != null) Process(work); }); //... db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget); sub.Publish(channel, "");
注:1.这种实现方式中数据并不是真正通过pub/sub传递的,pub/sub仅仅是通知,也就是说当有数据加入到队列中时,就去通知订阅者,让订阅者从列表中取出数据。
2.当有多个消费者订阅时,只有一个消费者能取到该值
3.如果没有消费者订阅时,数据将一直存在列表中
4.当你的消费者因为重启没收到加入新数据的通知时,你需要确保消费者能够处理这种积压的数据(这个似乎比较麻烦..)
参考资料:https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/PipelinesMultiplexers.md