【Redis】Redis数据类型List的安全队列和不安全队列
目录
长话短说
不安全:RPOP 命令将 消息 从队列中 移除并返回给客户端(此时队列中已经没有该消息),此时客户端崩溃,则该消息丢失。
安全:RPOPLPUSH 将消息从队列source (返回给客户端同时移到队列destination中,这个过程是原子操作),当客户端成功的处理了消息后,就可以把此消息从备份destination中移除。所以即使中途崩溃,客户端重启后可以从备份中找到消息。
详细
官方文档中有提到安全队列和不安全的队列:
一般情况下,我们可以借助List来实现消息队列,比如一个客户端通过命令LPUSH(BLPUSH)把消息入队,另一个客户端通过命令RPOP(BRPOP)获取消息。这种方式实现的队列是不安全的。
为什么是不安全的呢?因为RPOP命令的特性:会移除list的队尾元素(消息),并将这个元素(消息)返回给客户端。这意味着该元素就只存在于客户端的上下文中,redis服务器中没有这个元素了,如果客户端在处理这个返回元素的过程崩溃了,那么这个元素就永远丢失了。这种情况导致:客户端虽然成功收到了消息,但是却没有处理它。
那怎么来实现一个安全的队列呢?可以使用redis的 RPOPLPUSH (或者其阻塞版本的 BRPOPLPUSH)命令。
RPOPLPUSH命令格式:RPOPLPUSH source destination 。RPOPLPUSH命令原子性地返回并移除 source 列表的最后一个元素, 并把该元素放入 destination 列表的头部。使用这个命令就可以实现安全队列。
因为使用 RPOPLPUSH 获取消息时,RPOPLPUSH 会把消息返给客户端,同时把该消息放入一个备份消息列表,并且这个过程是原子的,可以保证消息的安全。当客户端成功的处理了消息后,就可以把此消息从备份列表中移除了。如果客户端因为崩溃的原因没有处理某个消息,那么就可以从备份列表destination中重新获取并处理这个消息。
原文:https://blog.csdn.net/aitangyong/article/details/51980702