Redis消息队列发展历程( 二 )


 
3 总结 
优势
 

  • 模型简单,和使用本地list基本相同,适配容易
 
  • 通过brpop做到消息处理的实时性
 
  • 通过rpoplpush来联动2个list,可以做到消息先消费后确认,避免消费者应用异常情况下消息丢失
 
不足
 
  • 消息只能被消费一次,缺乏广播机制
 
二 Redis 2.0 pubsublist作为消息队列应用场景受到限制很重要的原因在于没有广播,所以Redis 2.0中引入了一个新的数据结构pubsub 。pubsub虽然不能算作是list的替代品,但它确实能解决一些list不能解决的问题 。
 
1 pubsub特性 
pubsub引入一个概念叫channel,生产者通过publish接口投递消息时会指定channel,消费者通过subscribe接口订阅它关心的channel,调用subscribe后这条连接会进入一个特殊的状态,通常不能在发送其他请求,当有消息投递到这个channel时Redis服务端会立刻通过该连接将消息推送到消费者 。这里一个channel可以被多个应用订阅,消息会同时投递到每个订阅者,做到了消息的广播 。
 
另一方面,消费者可以会订阅一批channel,例如一个用户订阅了浙江的新闻的推送,但浙江新闻还会进行细分,例如“浙江杭州xx”、“浙江温州xx”,这里订阅者不需要获取浙江的所有子类在挨个订阅,只需要调用psubscribe“浙江*”就能订阅所有以浙江开头的新闻推送了,这里psubscribe传入一个通配符表达的channel,Redis服务端按照规则推送所有匹配channel的消息给对应的客户端 。
 
#基于pubsub完成channel的匹配和消息的广播#消费者1订阅channel1subscribe channel11) "subscribe"2) "channel1"3) (integer) 1#收到消息推送1) "message"2) "channel1"3) "msg1"#消费者2订阅channel*psubscribe channel*1) "psubscribe"2) "channel*"3) (integer) 1#收到消息推送1) "pmessage"2) "channel*"3) "channel1"4) "msg1"1) "pmessage"2) "channel*"3) "channel2"4) "msg2"#生产者发布消息msg1和msg2publish channel1 msg1(integer) 2publish channel2 msg2(integer) 1
Redis消息队列发展历程

文章插图
 
在Redfis 2.8时加入了keyspace notifications功能,此时pubsub除了通知用户自定义消息,也可以通知系统内部消息 。keyspace notifications引入了2个特殊的channel分别是__keyevent@<db>__:<event>和__keyspace@<db>__:<key>,通过订阅__keyevent客户端可以收到某个具体命令调用的回调通知,通过订阅__keyspace客户端可以收到目标key的增删改操作以及过期事件 。使用这个功能还需要开启配置notify-keyspace-events 。
 
#通过keyspace notifications功能获取系统事件#写入请求set testkey v EX 1#订阅key级别的事件psubscribe __keyspace@0__:testkey1) "psubscribe"2) "__keyspace@0__:testkey"3) (integer) 1#收到通知1) "pmessage"2) "__keyspace@0__:testkey"3) "__keyspace@0__:testkey"4) "set"1) "pmessage"2) "__keyspace@0__:testkey"3) "__keyspace@0__:testkey"4) "expire"1) "pmessage"2) "__keyspace@0__:testkey"3) "__keyspace@0__:testkey"4) "expired"#订阅所有的命令事件psubscribe __keyevent@0__:*1) "psubscribe"2) "__keyevent@0__:*"3) (integer) 1#收到通知1) "pmessage"2) "__keyevent@0__:*"3) "__keyevent@0__:set"4) "testkey"1) "pmessage"2) "__keyevent@0__:*"3) "__keyevent@0__:expire"4) "testkey"1) "pmessage"2) "__keyevent@0__:*"3) "__keyevent@0__:expired"4) "testkey"2 pubsub的不足之处 
pubsub既能单播又能广播,还支持channel的简单正则匹配,功能上已经能满足大部分业务的需求,而且这个接口发布的时间很早,在2011年Redis 2.0发布时就已经具备,用户基础很广泛,所以现在很多业务都有用到这个功能 。但你要深入了解pubsub的原理后,是肯定不敢把它作为一个一致性要求较高,数据量较大系统的消息服务的 。
 
首先,pubsub的消息数据是瞬时的,它在Redis服务端不做保存,publish发送到Redis的消息会立刻推送到所有当时subscribe连接的客户端,如果当时客户端因为网络问题断连,那么就会错过这条消息,当客户端重连后,它没法重新获取之前那条消息,甚至无法判断是否有消息丢失 。


推荐阅读