Redis Jingjin — сценарии использования и применения списка
В последнее время я изучаю Redis в Jingjin и учусь, пока пишу.
Как перед чтением, выработайте привычку
1. Инструкции по использованию типа Список
- Тип списка используется для хранения нескольких упорядоченных строк и поддерживает хранение 2^32-1 элементов.
- Redis может вставлять (pubsh) и извлекать (pop) элементы с обоих концов связанного списка, действуя как очередь или стек.
- Поддерживает чтение указанного диапазона наборов элементов
- Прочитать элемент по указанному индексу и т. д.
注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)
另外当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。
2. Общие команды типа String:
Справа налево налево: очередь
# 进入队列
> rpush books python java golang
(integer) 3
# 队列长度
> llen books
(integer) 3
# 取出队列
> lpop books
"python"
> lpop books
"java"
> lpop books
"golang"
> lpop books
(nil)
Прямо на входе, прямо на выходе: стек
# 入栈
> rpush books python java golang
(integer) 3
# 出栈
> rpop books
"golang"
> rpop books
"java"
> rpop books
"python"
> rpop books
(nil)
медленная работа
lindex эквивалентен методу get(int index) связанного списка Java, он должен пройти по связанному списку, и производительность ухудшается по мере увеличения индекса параметра.
> rpush books python java golang
(integer) 3
> lindex books 1 # O(n) 慎用
"java"
> lrange books 0 -1 # 获取所有元素,O(n) 慎用
1) "python"
2) "java"
3) "golang"
> ltrim books 1 0 # O(n) 慎用 这其实是清空了整个列表,因为区间范围长度为负
OK
> llen books
(integer) 0
ltrim не совсем то же самое, что буквальное значение, не столько去除
скорее сказать保留
.
Потому что два параметра start_index и end_index ltrim определяют диапазон значений, которые будут сохранены.
Это делает его идеальным для реализации связанного списка фиксированной длины.
3. Сценарии использования:链表
используется для изготовления异步队列
链表
обычно используется, чтобы делать异步队列
использовать
-
понадобится
延后
выполненные задачи结构体序列化(JSON)
помещать в список Redis в виде строки -
Другой поток запрашивает данные из этого списка для обработки.
-
lpush
+lpop
= складывать первым в последний из стека -
lpush
+rpop
= очередь в порядке очереди -
lpush
+ltrim
= закрытая коллекция -
lpush
+brpop
= очередь сообщений очередь сообщений
Очередь Redis нельзя обойти消息丢失
проблема
Очереди сообщений обычно реализуются с помощью List:
- Поставьте сообщение в очередь с помощью команды LPUSH (BLPUSH)
- Получить сообщения командой RPOP (БРОПОП).
Но реализованная таким образом очередь不安全
из.
Из-за характера команды RPOP (BRPOP):
-
移除
Конечный элемент (сообщение) списка возвращается клиенту. В это время элемент只存在
В контексте клиента на сервере Redis没有
этот элемент. - Если клиент находится в процессе обработки элемента
崩溃
, то элемент потерян навсегда. Эта ситуация приводит к:客户端虽然成功收到了消息,但是却没有处理它
.
попытаться спасти
Как я могу добиться более безопасной очереди?
Попробуйте RedisRPOPLPUSH
(или его блокирующая версияBRPOPLPUSH
)Заказ.
В частности, операция:
- Когда очередь A помещает элементы (и удаляет их), сохраняйте элементы в очередь B.
- Если клиент, обрабатывающий элемент, дает сбой, его также можно найти в очереди B.
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"
redis>
Есть две проблемы с этим методом,
- Несколько потребителей одновременно передают сообщения во вторую очередь, и во второй очереди будет накапливаться (выполненное, невыполненное) сообщение.
- Предполагая, что ваше сообщение является особенным и его содержание не будет повторяться, вы можете пройти
lrem a 0 "元素"
Функция находит и удаляет сообщение. Кроме того, количество сообщений в очереди, с которой сталкивается клиент, запущенный для обработки второй очереди, должно быть небольшим. быть извлечены с использованием параллелизма.Очередь 2, если выскочить из очереди 2, то это вернется к проблеме, которую мы собирались избежать.
Наконец
Так что бросьте и попробуйте найти Redislist
- Трудно сделать ACK подтверждения потребителя
- Его нельзя использовать повторно, после употребления он будет удален.
- Очередь не дедуплицируется
Поэтому для сценариев с высокими требованиями к согласованности рекомендуется использовать Redis 5 Stream или RocketMQ для очередей. Я не нашел сценарий, который особенно подходит для использования списка Redis. Если вы думаете об этом, пожалуйста, оставьте сообщение для связи ❤️