Redis Jingjin — сценарии использования и применения списка

Redis
Redis Jingjin — сценарии использования и применения списка

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. Если вы думаете об этом, пожалуйста, оставьте сообщение для связи ❤️

Категории