本文内容为 http://www.redis.io/commands/rpoplpush 的翻译、注解、例子扩充及其它修改。感谢 Redis 作者 Antirez 为开源社区作出的贡献,本文保证最新、最准、最全以表示对其的敬意。欢迎留言纠错、提示更新或支持。
RPOPLPUSH source destination

原子地(Atomically)返回(Return)及删除(Remove)source 对应的列表中的最后一个元素(即尾部(Tail)),然后再将该元素压入(Push)键 destination 对应的列表中的第一个元素位置处(即头部(Head))。

Atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination.

举个例子,假如存在源列表 a、b、c,及目标列表 x、y、x,执行当前命令后,源列表变为 a、b,目标列表变为 c、x、y、z

如果键 source 是空的,将会返回 nil,且不进行任何操作。如果键 source 及键 destination 相同,当前操作等同于从列表末尾删除元素,后然压入列表头,所以,该命令可以用于列表循环(Rotation )自转。

If source does not exist, the value nil is returned and no operation is performed. If source and destination are the same, the operation is equivalent to removing the last element from the list and pushing it as first element of the list, so it can be considered as a list rotation command.
  • 被执行弹出压入操作的元素。

    Bulk string reply: the element being popped and pushed.
  • redis> RPUSH mylist "one"
    (integer) 1
    redis> RPUSH mylist "two"
    (integer) 2
    redis> RPUSH mylist "three"
    (integer) 3
    redis> RPOPLPUSH mylist myotherlist
    "three"
    redis> LRANGE mylist 0 -1
    1) "one"
    2) "two"
    redis> LRANGE myotherlist 0 -1
    1) "three"
  • Pattern: Reliable queue

    Redis is often used as a messaging server to implement processing of background jobs or other kinds of messaging tasks. A simple form of queue is often obtained pushing values into a list in the producer side, and waiting for this values in the consumer side using RPOP (using polling), or BRPOP if the client is better served by a blocking operation.

    However in this context the obtained queue is not reliable as messages can be lost, for example in the case there is a network problem or if the consumer crashes just after the message is received but it is still to process.

    RPOPLPUSH (or BRPOPLPUSH for the blocking variant) offers a way to avoid this problem: the consumer fetches the message and at the same time pushes it into a processing list. It will use the LREM command in order to remove the message from the processing list once the message has been processed.

    An additional client may monitor the processing list for items that remain there for too much time, and will push those timed out items into the queue again if needed.

  • Pattern: Circular list

    Using RPOPLPUSH with the same source and destination key, a client can visit all the elements of an N-elements list, one after the other, in O(N) without transferring the full list from the server to the client using a single LRANGE operation.

    The above pattern works even if the following two conditions: * There are multiple clients rotating the list: they'll fetch different elements, until all the elements of the list are visited, and the process restarts. * Even if other clients are actively pushing new items at the end of the list.

    The above makes it very simple to implement a system where a set of items must be processed by N workers continuously as fast as possible. An example is a monitoring system that must check that a set of web sites are reachable, with the smallest delay possible, using a number of parallel workers.

    Note that this implementation of workers is trivially scalable and reliable, because even if a message is lost the item is still in the queue and will be processed at the next iteration.

  • 版本支持

    1.2.0+

    时间复杂度(Time complexity)

    O(1)