总结
目前使用redis做消息队列的的方式有3中,list, publish/subscribe, stream
list做mq的总结
使用方法
1. 生产者可以 lpush 写入消息,消费者可以 rpop 读取消息,也就是pull模式
2. 消费者可以使用 brpop 阻塞性读取消息,约等于服务器端的实时推送
3. 如何保证消息读取但未处理时,消费者程序异常宕机造成的消息丢失,答案:rpoplpush 或 brpoplpush ,即先从原队列中移除一个消息并插入到一个新队列,消费者处理完该消息后再从新队列中删除,相当于ack机制,避免消费者异常时消息丢失
缺点
1.一个消息只能被消费一次,缺乏广播机制
缺点举例:游戏开发中,玩家登陆时,很多进程需要监听该登陆消息做对应的处理,但是因为list消息只能被消费一次,无法满足需求(虽然你可以为登陆事件搞多个list,每个关心登陆事件的进程监听一个list,登陆时也把一个消息压入多个list,只是生产者消费者太过耦合)
publish/subscribe
使用方法
1. 生产者可以 publish 写入消息,消费者可以 subscribe 监听消息,也就是push模式
2. 多个消费者可以 subscribe 同一个消息,消费者publist后,所有的消费者都能收到通知,以此解决了list中一个消息只能被消费一次的缺点
3. 可以使用通配符*进行简单的正则匹配,比如多个类似channel(广东深圳频道,广东广州频道,广东东莞频道)这个时候消费者可以 subscribe 广东*频道 来监听所有这样的频道
缺点
1. 解决了list做mq时消息不能广播的问题
2. 服务器是即时推送,不保存消息,所以消费者一旦断线,消息就丢失了
3. 消息无堆积,不能削峰填谷。因为服务器不考虑消费者,只按照生产者的速度推送。若消费者速度慢,消息就会在client连接的buf中堆积,超过阀值后会断开连接,这样消息就全部丢失了
stream
使用方法
具体使用过可参考笔者的这篇博客
redis 流 stream的使用总结 - 基础命令_YZF_Kevin的博客
优点
1. 完全对标kafka的模型重新设计的全内存的mq,速度高于kafka
2. pull模式,且有ack机制。且数据也会随着持久化保存在rdb和aof文件中,即使redis重启,保证数据不会丢失
3. 有消费者组的概念,一个topic可以有多个消费者组,一个消费者组内可以有多个消费者,既支持消息广播(一条msg能被多个不同的消费者组重复消费),又可以水平扩展(一个消费者组内增加多个消费者依次增加处理速度)
缺点
1. 完全用内存做消息堆积,相比那些以硬盘做堆积的,成本较高
2. redis存在数据丢失的可能性(单点redis持久化时everysec也可能会丢失一秒的数据;集群redis的主从同步也可能会丢失数据)
标签:消费者,队列,redis,list,subscribe,mq,消息,丢失 From: https://blog.51cto.com/u_15912066/5936254