总结

目前使用redis做消息队列的的方式有3中,list,      publish/subscribe,       stream

list做mq的总结

使用方法

1. 生产者可以 lpush 写入消息,消费者可以 rpop 读取消息,也就是pull模式

2. 消费者可以使用 brpop 阻塞性读取消息,约等于服务器端的实时推送

3. 如何保证消息读取但未处理时,消费者程序异常宕机造成的消息丢失,答案:rpoplpushbrpoplpush ,即先从原队列中移除一个消息并插入到一个新队列,消费者处理完该消息后再从新队列中删除,相当于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的博客-CSDN博客_redis 流

优点

1. 完全对标kafka的模型重新设计的全内存的mq,速度高于kafka

2. pull模式,且有ack机制。且数据也会随着持久化保存在rdb和aof文件中,即使redis重启,保证数据不会丢失

3. 有消费者组的概念,一个topic可以有多个消费者组,一个消费者组内可以有多个消费者,既支持消息广播(一条msg能被多个不同的消费者组重复消费),又可以水平扩展(一个消费者组内增加多个消费者依次增加处理速度)

缺点

1. 完全用内存做消息堆积,相比那些以硬盘做堆积的,成本较高

2. redis存在数据丢失的可能性(单点redis持久化时everysec也可能会丢失一秒的数据;集群redis的主从同步也可能会丢失数据)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐