Redis 实现安全队列

Redis的列表数据结构可以让我们方便的实现消息队列


例如用 LPUSH(BLPUSH)把消息入队,用 RPOP(BRPOP)获取消息


绝大部分的情况下,这些操作都是没问题的,但并不能保证绝对安全


当 LPOP 返回一个元素给客户端的时候,会从 list 中把该元素移除,这意味着该元素就只存在于客户端的上下文中,如果客户端在处理这个返回元素的过程崩溃了,那么这个元素就永远丢失了


如何解决?


redis 有一个 RPOPLPUSH (或者其阻塞版本的 BRPOPLPUSH)命令


命令格式


RPOPLPUSH source destination 


原子性地返回并移除 source 列表的最后一个元素, 并把该元素放入 destination 列表的头部


用这个命令可以保证队列的安全问题:


使用 RPOPLPUSH 获取消息时,RPOPLPUSH 会把消息返给客户端,同时把该消息放入一个备份消息列表,并且这个过程是原子的,可以保证消息的安全,当客户端成功的处理了消息后,就可以把此消息从备份列表中移除了


命令的阻塞与非阻塞区别


redis的命令中,很多都提供了阻塞与非阻塞两个方式


例如 LPUSH 为非阻塞,BLPUSH 为阻塞方式


他们的区别是什么?


唯一的区别是当列表中没有元素时,BRPOP命令会一直阻塞住连接,直到有新元素加入,而RPOP会直接返回nil


实际应用的区别


需要从队列获取任务


如果用非阻塞的方式,代码会是这样


# 无限循环读取任务队列中的内容 

loop 

$task = RPOR queue 

if $task 

# 如果有任务则执行 

execute($task) 

else 

# 如果没有就等待1秒

wait 1 second 


当队列中没有任务时,每秒都会调用一次RPOP命令查看是否有新任务,可能会白白浪费很多系统资源,如果在有新任务加入队列时就通知消费者就好了,这个需求就可以使用阻塞式命令来实现


loop 

# 如果队列中没有任务,BRPOP命令会一直阻塞

# 0 表示一直等待,永不过期 

$task = BRPOP queue, 0 

# 有返回值就继续执行 

execute($task[1])



https://www.cnblogs.com/wangdaijun/p/6497403.html



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值