Redis: принципы реализации и сценарии предотвращения ошибок при публикации и подписке (pub/sub)
Redis: принципы реализации и сценарии предотвращения ошибок при публикации и подписке (pub/sub)

Введение


Redis публикация и подписка (pub/sub) — это модель передачи сообщений: отправитель (pub) отправляет сообщения в канал (channel), а подписчик (sub) получает сообщения из канала (channel).

Redis в настоящее время поддерживает обычные подписки и подписки на шаблоны (шаблоны в стиле glob). Давайте воспользуемся обычной подпиской, чтобы понять принцип ее реализации.

Обычная подписка-публикация и принцип реализации подписки (pub/sub).


  • Хранение отношений подписки

RedisСерверСловарь используется для хранения отношений подписки.。существоватьRedis-7.0.5Отражение в исходном коде:

(Источник: Redis-7.0.5: server.h --->struct redisServer )

Язык кода:javascript
копировать

Базовая реализация словаря используетРеализовано с использованием хеш-массива, ключом является имя канала, значением является связанный список (связанный список, состоящий из клиентов, подписавшихся на один и тот же канал), а элементы связанного списка представляют собой связанные клиентские объекты.

(Источник: Redis-7.0.5: server.h --->typedef struct client )

Используйте метод цепочки адресов для разрешения конфликтов хэшей(Сохраните все пары ключ-значение с конфликтующими хеш-адресами.связанный списоксередина)。

Чтобы подсчитать информацию о канале, на которую подписан клиент, структура client, которая инкапсулирует информацию о клиенте, также использует структуру данных словаря для избыточного сохранения всех названий каналов, на которые подписан клиент, в пространственно-временном режиме (поведение словаря выраженный как структура данных коллекции).

(Источник: Redis-7.0.5: server.h --->typedef struct client )

  • Процесс подписки

В качестве примера возьмем название канала Renzhikeji:

Функция обработки команды: subscribeCommand (файл pubsub.c)

(Источник: Redis-7.0.5: pubsub.c --> void subscribeCommand(client *c))

Команда подписки: ПОДПИСАТЬСЯ channel [channel ...],Поддерживает подписку на несколько каналов,В строке кода 27,Вызовите функцию pubsubSubscribeChannel для каждого канала в массиве каналов.,Сохраните отношения подписки на каналы в хэш-словаре.

Сначала добавьте пару ключ-значение: имя канала. -> null Сохраните его в хэш-словаре клиента pubsub_channels для поддержки команды, позволяющей легко получать информацию обо всех каналах, на которые подписан этот клиент (что соответствует строке кода 234).

Затем из хэш-словаря сервера В pubsub_channels запросите это значение ключа для связанного клиента, соответствующего текущему имени канала. список (соответствует строке кода 238), если не найден, создать Пустой связанный список,ВоляПара ключ-значение: название канала -> Пустой связанный список Сохраните его в хеш-словаре (соответствует строкам кода 239–242). Если вы нашли клиентсвязанный, соответствующий текущему названию канала с этим значением ключа список(Соответствующая строка кода244)Затем получите текущую пару ключ-значениеvalueценить。наконецДобавьте клиента, который в данный момент подписан на этот канал, в конец связанного списка.(Соответствующая строка кода246)。

Видно, что основным процессом подписки является операция поиска и добавления хеш-таблицы.

  • Процесс публикации новостей

В качестве примера возьмем название канала Renzhikeji:

Функция обработки команд публикации сообщений: publicCommand (файл pubsub.c).

(Источник: Redis-7.0.5: pubsub.c --> void publishCommand(client *c) )

Сначала определите, запущен ли он в дозорном режиме. Если да, обработайте процесс обработки сообщения публикации в дозорном режиме.

Если это не дозорный режим, вызовите функцию

pubsubPublishMessageAndPropagateToCluster :

1、Из словаря структуры данных server.pubsub_channels (отношения подписки) найдите всех подписчиков этого канала и запишите сообщения, опубликованные этим каналом, в соответствующие кэши ответов всех соответствующих клиентов-подписчиков.

Из словаря server.pubsub_channels, по названию каналадляkey,Найти пары ключ-значение dictEntry,если найден,Перейдите по связанному списку клиентов, соответствующему ключу,Воля Функция вызова опубликованного сообщенияaddReplyPubsubMessage Запись в кэш ответов клиента,и обновляет статистику памяти (и, конечно, перебирает словарь подписки на схему).

Примечание. Если кэш, соответствующий клиенту, превысит лимит, подписчик будет принудительно закрыт.

(Источник: Redis-7.0.5: networking.c )

2. Если сервер включает режим кластера (server.cluster_enabled), будет вызвана функция кластераPropagatePublish для управления отношениями подписки «главный-подчиненный» кластера.

Язык кода:javascript
копировать

Краткое описание того, как избежать ловушек


  • Из-за отношения публиковатьподписаться, реализованного в Redis, в памяти сохраняется только структура словаря. данныхсередина,И опубликованное сообщение не будет сохранено,Это приведет к тому, что клиент отключится от сети или снова вернется в сеть.,ноВ этот период времени, когда вы не в сети, на опубликованные сообщения подписка не производится.
  • Кэш ответов в объекте redisclientclient ограничен.,При превышении лимита клиент будет вынужден закрыться.,Требуется, чтобы клиент обрабатывал отношения повторной подписки.
  • Эту реализацию публикации и подписки Redis нельзя использовать в качестве очереди сообщений, такой как rocktmq.


boy illustration
Статья длиной в 9000 слов знакомит вас с процессом запуска SpringBoot — самым подробным процессом запуска SpringBoot в истории — с изображениями и текстом.
boy illustration
Как настроить размер экрана в PR. Учебное пособие по настройке размера видео в PR [подробное объяснение]
boy illustration
Элегантный и мощный: упростите операции ElasticSearch с помощью easy-es
boy illustration
Проект аутентификации по микросервисному токену: концепция и практика
boy illustration
【Java】Решено: org.springframework.http.converter.HttpMessageNotWritableException.
boy illustration
Изучите Kimi Smart Assistant: как использовать сверхдлинный текст, чтобы открыть новую сферу эффективной обработки информации
boy illustration
Начало работы с Docker: использование томов данных и монтирования файлов для хранения и совместного использования данных
boy illustration
Использование Python для реализации автоматической публикации статей в публичном аккаунте WeChat
boy illustration
Разберитесь в механизме и принципах взаимодействия потребителя и брокера Kafka в одной статье.
boy illustration
Spring Boot — использование Resilience4j-Circuitbreaker для реализации режима автоматического выключателя_предотвращения каскадных сбоев
boy illustration
13. Springboot интегрирует Protobuf
boy illustration
Примечание. Инструмент управления батареями Dell Dell Power Manager
boy illustration
Общая интерпретация класса LocalDate [java]
boy illustration
[Базовые знания ASP.NET Core] -- Веб-API -- Создание и настройка веб-API (1)
boy illustration
Настоящий бой! Подключите Passkey к своему веб-сайту для безопасного входа в систему без пароля.
boy illustration
Руководство по настройке Nginx: как найти, интерпретировать и оптимизировать настройки Nginx в Linux
boy illustration
Typecho отображает использование памяти сервера
boy illustration
Как вставить элемент перед указанным ключом в ассоциативный массив в PHP
boy illustration
swagger2 экспортирует API как текстовый документ (реализация Java) [легко понять]
boy illustration
Выбор фреймворка nodejs Express koa egg MidwayJS сравнение NestJS
boy illustration
Руководство по загрузке, установке и использованию SVN «Рекомендуемая коллекция»
boy illustration
Интерфейс PHPforwarding_php отправляет запрос на получение
boy illustration
Создавайте и защищайте связь в реальном времени с помощью SignalR и Azure Active Directory.
boy illustration
ВичатПубличная платформаразвивать(три)——ВичатQR-кодгенерировать&Сканировать кодсосредоточиться на
boy illustration
[Углубленное понимание Java IO] Используйте InputStreamReader для чтения содержимого файла и легкого выполнения задач преобразования текста.
boy illustration
сравнение строк PHP
boy illustration
9 сценариев асинхронного сбоя @Async
boy illustration
Эффективная обработка запланированных задач: углубленное изучение секретов библиотеки APScheduler на Python
boy illustration
Рекомендации по облегченному артефакту развязки внутренних компонентов Spring Event (событие Spring)
boy illustration
Go: Лесоруб-лесоруб на колесах Введение