RPOPLPUSH
RPOPLPUSH (deprecated)
Начиная с версии Redis 6.2.0, эта команда считается устаревшей.
Её можно заменить на LMOVE с аргументами RIGHT и LEFT при миграции или написании нового кода.
RPOPLPUSH source destination
- Доступна с версии:
- 1.2.0
- Временная сложность:
- O(1)
- Категории ACL:
-
@write,@list,@slow,
Атомарно возвращает и удаляет последний элемент (хвост) списка, хранящегося в source, и добавляет элемент в начало (голову) списка, хранящегося в destination.
Например: предположим, что source содержит список a,b,c, а destination содержит список x,y,z. Выполнение RPOPLPUSH приводит к тому, что source содержит a,b, а destination содержит c,x,y,z.
Если source не существует, возвращается значение nil, и никакая операция не выполняется. Если source и destination одинаковы, операция эквивалентна удалению последнего элемента из списка и добавлению его в начало списка, поэтому её можно рассматривать как команду вращения списка.
Возврат
Ответ с текстовой строкой: элемент, который был извлечён и добавлен.
Примеры
RPUSH mylist "one" RPUSH mylist "two" RPUSH mylist "three" RPOPLPUSH mylist myotherlist LRANGE mylist 0 -1 LRANGE myotherlist 0 -1
Шаблон: надёжная очередь
Redis часто используется в качестве сервера обмена сообщениями для реализации обработки фоновых задач или других видов задач обмена сообщениями. Простой вид очереди часто получается путём добавления значений в список на стороне производителя и ожидания этих значений на стороне потребителя с помощью RPOP (с помощью опроса) или BRPOP, если клиенту лучше подходит блокирующая операция.
Однако в этом контексте полученная очередь не является надёжной, поскольку сообщения могут быть потеряны, например, в случае проблемы с сетью или если потребитель выходит из строя сразу после получения сообщения, но до обработки.
RPOPLPUSH (или BRPOPLPUSH для блокирующего варианта) предлагает способ избежать этой проблемы: потребитель извлекает сообщение и одновременно добавляет его в список обработки. Он будет использовать команду LREM, чтобы удалить сообщение из списка обработки после того, как оно было обработано.
Дополнительный клиент может отслеживать список обработки на предмет элементов, которые остаются там слишком долго, и по необходимости возвращать истекшие по времени элементы в очередь.
Шаблон: циклический список
Использование RPOPLPUSH с одинаковым ключом источника и назначения позволяет клиенту посетить все элементы списка из N элементов по одному за раз, в O(N), не передавая весь список с сервера на клиент с помощью одной операции LRANGE.
Вышеупомянутый шаблон работает даже в том случае, если выполняются одно или оба из следующих условий:
- Несколько клиентов вращают список: они будут получать разные элементы, пока все элементы списка не будут посещены, и процесс начнётся заново.
- Другие клиенты активно добавляют новые элементы в конец списка.
Это существенно упрощает реализацию системы, в которой набор элементов должен непрерывно обрабатываться N работниками как можно быстрее. Пример — система мониторинга, которая должна проверять, доступны ли набор веб-сайтов, с минимальной задержкой, используя несколько параллельных рабочих процессов.
Обратите внимание, что эта реализация рабочих процессов тривиально масштабируема и надёжна, поскольку даже если сообщение потеряно, элемент всё ещё находится в очереди и будет обработан на следующей итерации.
© 2006–2022 Salvatore Sanfilippo
Licensed under the Creative Commons Attribution-ShareAlike License 4.0.
https://redis.io/commands/rpoplpush/