Недавно я заново изучил Redis и был глубоко впечатлен очарованием Redis, я узнал, что Redis не только быстр, но и медленен (я думаю, что он еще и так хорош, о(╥﹏╥)о), это мощный инструмент .
Кекекеке, не поймите меня неправильно, эта статья очень серьезная!
Что ж, вернемся к нашей теме, все мы знаем, что Redis — это однопроцессорная однопоточная база данных, основанная на памяти (Redis 6.0 поддерживает многопоточность после старта!), и скорость обработки очень высокая. Так почему же Redis медленный? Оказывается, упомянутая здесь медлительность означает, что Redis может задавать некоторые параметры для достижения результата медленной обработки. (Вот почему Redis может быть как быстрым, так и медленным!)
Тогда поговорим о том, как наша модель Redis реализует задержку в очереди:
В нашей повседневной жизни мы можем найти,
- Заказы, размещенные на торговых платформах, таких как Taobao и JD.com, будут автоматически отменены, если платеж не будет произведен в течение определенного периода времени.
- При принятии такси, если владелец автомобиля не требует заказа в течение указанного времени, платформа отменит ваш заказ и напоминает вам, что владелец автомобиля не принял заказ на время.
- При заказе на вынос, если продавец не принял заказ в течение 10 минут, заказ будет автоматически отменен.
- При получении экспресса, если мы не подтвердим получение, программа автоматически выполнит заказ через определенный промежуток времени.
- После того, как платформа завершит заказ, если мы не прокомментируем продукт в течение указанного времени, по умолчанию покупатель автоматически не прокомментирует.
- ....и многие другие подобные сценарии.
В этот момент мы можем подумать, почему мы это делаем?
Поскольку это может гарантировать, что инвентарь продукта может быть выпущен для покупки другими людьми, вам не нужно ждать такси и не получать ответа, вы можете вовремя перейти в другой магазин, чтобы заказать еду на вынос.
Так как же достигаются эти ситуации?
На этом этапе мы можем посмотреть на эту диаграмму, чтобы увидеть, как обрабатываются задержки сообщений:
Когда пользователь отправляет запрос сообщения на фоновый сервер, сервер определяет, нужно ли задержать сообщение, при необходимости оно будет помещено в очередь задержки, а детектор отложенных задач обнаружит и обработает его. задачи, сервер немедленно обработает сообщение и соответственно вернет обработанный результат пользователю.
Внутри детектора отложенных задач есть две функции: запрос отложенных задач и выполнение отложенных задач.Детектор задач сначала перейдет к очереди отложенных задач, чтобы прочитать информацию в очереди и определить, какие задачи в текущей очереди истекли.И выводить и выполнять просроченную задачу (с характером реального времени будет определенная ошибка времени, т.к. это задача на время).
На данный момент мы можем подумать о том, какие команды можно использовать для установки флагов времени в структуре данных Redis?
Думали ли вы о команде zset, в которой есть функция сортировки с дедупликацией (сортировка по баллам). Да, ты прав!
Мы можем использовать команду zset (sortedset) для сортировки с установленной отметкой времени в качестве оценки, а также использовать команду zadd score1 value1 .... для создания сообщений в памяти все время. Затем используйте zrangebysocre, чтобы запросить все ожидающие задачи, соответствующие условиям, и выполнить задачи очереди в цикле. Вы также можете использовать ключ zrangebyscore min max withscores limit 0 1, чтобы запросить самую старую задачу для использования.
В общем, сделать это можно следующими двумя способами((^▽^) Если вы думаете о других методах, вы также можете сказать мне следующее~):
(1) Используйте zrangebyscore, чтобы запросить все задачи в текущей очереди задержки, найти все задачи задержки, которые необходимо обработать, и работать последовательно.
(2) Найдите самую раннюю текущую задачу и используйте значение оценки, чтобы определить, превышает ли время выполнения задачи текущее системное время, например: самое раннее время выполнения задачи — 3:00, а системное время — 2. :58), указывая на то, что это должно быть выполнено немедленно, время вышло (Чхончун, он идет, он идет, он идет со скоростью смерти).
Мы можем подумать о преимуществах Redis для реализации отложенных очередей?
На самом деле у Redis есть следующие преимущества для реализации отложенных очередей:
(1) Redis zset поддерживает высокопроизводительную сортировку результатов.
(2) Redis работает с памятью и работает очень быстро.
(3) Redis может создавать кластеры.Когда сообщений много, мы можем использовать кластеры для повышения скорости обработки сообщений и повышения доступности.
(4) В Redis есть механизм сохраняемости: при возникновении сбоя данные можно восстановить через AOF и RDB, что обеспечивает надежность данных.
В это время некоторые друзья спросят, есть ли другие способы реализации отложенных очередей! эммм.... Конечно есть, только неожиданного не бывает (О(∩_∩)О ха-ха~, шучу)
Во-первых, используйте промежуточное программное обеспечение сообщений для реализации очереди задержки.
(1) Реализация очередей задержки через RabbitMQ, то есть использование промежуточного программного обеспечения сообщений для реализации очередей задержки~
Способ 1: В MQ мы можем установить время истечения x-expires для очереди или установить время ожидания x-message-ttl для сообщения.
(Обратите внимание: сообщения с одинаковой задержкой должны помещаться в одну и ту же очередь, и для каждой задержки должна быть создана соответствующая очередь — это потому, что обнаружение истечения срока действия MQ является ленивым обнаружением.)
Способ 2. Мы можем использовать плагин RabbitMQ для реализации очереди задержки. Когда срок поставки достигнут и передать егоx-delayed-type
Тип переключателя с меткой типа отправляется в очередь назначения.
(2) RocketMQ реализует очередь задержки
Когда Rocketmq отправляет сообщение с задержкой, он сначала отправляет сообщение в указанную очередь в соответствии с периодом задержки (помещая сообщения с одинаковым периодом времени задержки в одну и ту же очередь, чтобы обеспечить порядок обработки сообщений, позволяя одинаковое время задержки сообщения). в очереди одинаковая, а сообщения о задержках во всем RocketMQ сортируются по возрастанию для обеспечения порядка обработки информации.). После этого таймер используется для опроса и обработки информации в этих очередях, чтобы определить, не истек ли срок ее действия. Сообщения с истекшим сроком действия будут отправлены в соответствующую очередь обработки для обработки.
Ха-ха, в настоящее время RocketMQ поддерживает только определенный период времени задержки, 1 с, 5 с, 10 с,... 2 часа, и не может поддерживать настройки задержки для любого периода времени. Заинтересованные друзья могут понять, что это связано с знанием ~
2. Kafka реализует команду задержки
Kafka настроила таймер (SystemTimer) для реализации функции задержки на основе колеса времени.Колесо времени (TimingWheel) в Kafka представляет собой циклическую очередь, в которой хранятся задачи по времени, и можно выполнять соответствующие настройки очереди задержки.
3. Netty реализует очередь с задержкой
Netty также реализует очередь с задержкой, основанную на циклическом алгоритме. Netty в основном использует HashedWheelTimer при построении очереди задержки.Основная структура данных HashedWheelTimer использует DelayedQueue, которая реализована алгоритмом колеса времени.
В-четвертых, DelayQueue для реализации очереди задержки
В Java есть собственный тип данных DelayQueue, и мы можем использовать его для реализации очереди с задержкой. DelayQueue инкапсулирует PriorityQueue (очередь с приоритетом). При добавлении элементов в очередь DelayQueue он присваивает элементу Задержку (время задержки) в качестве условия сортировки. Наименьший элемент в очереди будет помещен в начало очереди. элементы в очереди Из очереди разрешается извлекать только по истечении времени задержки. Эта реализация заключается в том, что данные хранятся в памяти и могут столкнуться с потерей данных, и она не может поддерживать распределенные системы.