Redis实现消息队列有两种形式:
广播订阅模式:基于Redis的 Pub/Sub 机制,一旦有客户端往某个key里面 publish一个消息,所有subscribe的客户端都会触发事件集群订阅模式:基于Redis List双向+ 原子性 + BRPOP (推荐学习:Redis视频教程)
Redis消息队列时,当Redis宕机后,消息可能会丢失(也要看持久化的策略)。如果收消息方未有重发和验证机制,Redis内的数据会出现丢失。所以,使用Redis的作为消息队列,通常是对于消息的准确性并非特别高的场景。
如果绝对的保证数据最终一致性,保证消息百分百不丢,那么需要:
1.写入时候要求启用事务处理,保证写一定成功。
2. redis配置成任何变更一定实时持久化,比如存储端是磁盘的话,每次变更马上同步写入磁盘,才算完成。redis是支持这种方式配置的,但是这么做会使它的内存数据库特性完全消失,性能变得十分低下。
3. 消费端也要实现事务方式,处理完成后,再回来真实删除消息。
4. 多线程或者多端同时并发处理,可以通过锁的方式来规避。
3 4的需求需要自己实现,可以一起考虑,用另外一个队列实现的方式也可以,但是更好的方式是在队列内部实现个计数器。hash格式的加个字段加数值,list的先推一个数值打底,string的头上加个数值再加个分隔符,就可以做个简单计数器了,虽然土,胜在够实用。
除了特定的系统之外,一般不会要求这么强的一致性,实现倒不难,但是性能会很差很差。
银行类支付类业务会要求严格的事务一致性,而互联网类业务一般会用点取巧的方式,就是可以容忍极短时间内少量数据丢失的方式,换取更高性能。
比如上面的redis处理,可以改为1000条数据变更的时候再真实落盘,即写入磁盘。那么极限情况下,如突然断电,存在可能丢失这1000条数据的风险。当然这种情况出现的概率也是很低的(远离蓝翔挖掘机?),所以大部分场景下可以接受。
更多Redis相关技术文章,请访问Redis入门教程栏目进行学习!
以上就是redis消息队列如何防止数据丢失的详细内容,转载自php中文网
发表评论 取消回复