Как использовать Redis для отправки подписки в реальном времени

Redis

Мой официальный аккаунт:MarkerHub, веб-сайт Java:markerhub.com

Чтобы увидеть больше избранных статей, нажмите:Java Notes Daquan.md

Малый концентратор ведет к чтению:

Как добиться одновременного завершения в секундах для 20+ пользователей push-уведомлений В этой статье представлены три схемы, MQ, традиционные задачи синхронизации и очередь SortSet Redis, последовательно анализируется осуществимость и, наконец, приводится логика Redis и некоторые реализации кода. Вы научились этому?


Некоторое время назад я разработал проект ваучерного центра компании, в основе которого лежит ключевая технология redis.

Давайте сначала поговорим о проекте центра ваучеров.Этот проект похож на центр ваучеров приложения Jingdong.Конечно, изображение взято с JD.com, а не компании. . .

Для купонов есть функция под названием подписка push.

Что такое подписка на купоны?

То есть пользователь подписался на отправку купона, и информация о напоминании будет отправлена ​​в приложение пользователя за одну минуту до того, как ее можно будет запросить.

Изначально эту функцию подписки должен был выполнять центр сообщений, но сказали, что это невозможно сделать в короткие сроки. Так что позвольте мне, ответственному за талоны, сделать -.-!. Конкретный план заключается в том, что, когда достигается конкретный момент времени отправки, система купонов вызывает интерфейс отправки центра сообщений для отправки информации.

Разберем бизнес-сценарий этой функции. В настоящее время у компании 6000W+ зарегистрированных пользователей, поэтому не спрашивайте, кто это. . . Например, если есть купон на скидку без порога, то заказ будет уменьшен на 20 юаней, тогда этот купон заберет больше людей, мы консервативно оцениваем 10W+, что сложно сказать на уровне миллиона. Изначально мы установили число 200 000 человек, поэтому push-информация на 20 Вт будет отправлена ​​за одну минуту! И пользователь может подписаться на несколько купонов. Итак, мы знаем, что в этой функции подписки есть две заметные трудности:

  1. Эффективность push: если push идет медленно, пользователи будут жаловаться, что их вовремя не уведомили о том, что они упустили возможность открыть.

  2. Объем пуша большой: популярные купоны, все хотят урвать!

Однако объем толчка будет влиять на эффективность толчка. Это настоящая головная боль!

Итак, давайте решать проблемы одну за другой!

Вопрос об эффективности push: когда пользователь подписывается на напоминание о сборе купонов в центре купонов, в фоновом режиме будет сгенерирована запись напоминания о подписке пользователя, в которой фиксируется время отправки push-информации пользователю. Таким образом, возникает вопрос, как система может быстро выбирать, какие записи отправлять в режиме реального времени!

план 1:

Задержка доставки MQ. Хотя MQ поддерживает отложенную доставку сообщений, масштаб слишком велик, 1 с, 5 с, 10 с, 30 с, 1 мин, что невозможно использовать для доставки в точный момент времени! И если пользователь отменяет подписку после выполнения подписки, операция удаления отправленного сообщения MQ немного велика, и ее трудно выполнить за короткое время! И пользователи могут отменить и снова подписаться, что связано с проблемой дедупликации. Таким образом, решение MQ отклоняется.

Сценарий 2:

Традиционные задачи на время. Это относительно просто.Временная задача состоит в том, чтобы загрузить запись напоминания о подписке пользователя в базу данных и выбрать текущую запись, которую можно отправить. Но есть поговорка, что любой дизайн, оторванный от реального бизнеса, — это хулиган~. Давайте проанализируем, подходят ли для нашего бизнеса традиционные задачи на время!

Может ли он поддерживать несколько машин, работающих одновременно? Как правило, нет, может работать только на одной машине одновременно.
хранить источник данных Обычно это mysql или другие традиционные базы данных, а также однотабличное хранилище.
частота Поддержка секунд, минут, часов, дней, как правило, не слишком быстро

Таким образом, мы знаем, что общие традиционные задачи на время имеют следующие недостатки:

  1. узкое место производительности. Обрабатывает только одна машина, и она бессильна перед большими объемами данных!

  2. Низкая эффективность. Частота запланированных задач не может быть слишком высокой, так как слишком большая нагрузка на бизнес-базу данных!

  3. Единая точка отказа. Если машина, на которой вы работаете, зависнет, весь бизнес будет недоступен. - Это очень страшная вещь!

Поэтому традиционные запланированные задачи для этого бизнеса не подходят. . . 

Так мы в убытке? На самом деле нет! Нам просто нужно сделать простое преобразование в традиционную задачу на время! Его можно превратить в кластер задач по времени, который может работать на нескольких машинах одновременно, а эффективность может быть с точностью до второго уровня и отбрасывать единую точку отказа! Для этого требуется помощь нашего мощного Redis.

Вариант 3: Кластер запланированных задач

Прежде всего, нам нужно определить три задачи, которые будет решать кластер запланированных задач!

1. Высокая эффективность

2. Пропускная способность должна быть большой

3. Сервис должен быть стабильным и не должно быть единой точки отказа

Ниже представлена ​​схема архитектуры всего кластера запланированных задач. 

Архитектура очень проста: мы храним push-записи подписки пользователя в очереди sortedSet кластера Redis и используем метку времени напоминания в качестве значения оценки, а затем запускаем таймер на каждом из наших бизнес-серверов с частотой в секундах. Параметр равен 1 с, и после балансировки нагрузки пользовательские записи, подлежащие отправке, получаются из очереди и отправляются. Ниже мы анализируем следующую архитектуру.

1. Производительность. За исключением других факторов, таких как пропускная способность, она в основном линейно связана с количеством машин. Чем больше количество машин, тем больше пропускная способность, и относительная пропускная способность уменьшается, когда количество машин невелико.

2. Эффективность: повышен до второго уровня, эффект приемлемый.

3. Единая точка отказа? несуществующий! Если только кластер Redis или все серверы не отключены. . . .

Вот анализ того, почему используется Redis?

Во-первых, Redis можно использовать в качестве высокопроизводительного хранилища БД с гораздо более высокой производительностью, чем у MySQL, и поддерживает постоянство и хорошую стабильность.

Вторая очередь Redis SortedSet, естественно, поддерживает сортировку по времени в качестве условия, что идеально подходит для выбора записей для отправки.

хорошо~ Поскольку план уже существует, как реализовать его за один день? Да, я разработал эту программу для завершения базового кодирования, и время составляет один день. . . Потому что время слишком быстро.

Сначала мы используем user_id в качестве ключа, а затем номер очереди мода хэшируется в очередь Redis SortedSet. Почему так, ведь если пользователь подписывается на два купона одновременно и время пуша очень близко, то такие два пуша можно объединить в один ~, и хеш будет относительно равномерным. Вот скриншот части кода:

  

Затем нам нужно определить количество очередей, вообще говоря, мы определяем столько очередей, сколько у нас есть серверов обработки. Поскольку слишком малое количество очередей вызовет конкуренцию очередей, слишком большое количество может привести к тому, что записи не будут обработаны вовремя.

Однако рекомендуется, чтобы количество очередей настраивалось динамически, поскольку количество компьютеров кластера в линии будет часто меняться. Мы добавим машины во время большой акции, и по мере увеличения объема бизнеса количество машин также будет увеличиваться, верно? Поэтому я позаимствовал алмаз Taobao для динамической настройки количества очередей.

 

Сколько записей мы берем из очереди каждый раз, также можно настроить динамически.

Таким образом, пропускная способность всего кластера может быть скорректирована в любое время в соответствии с реальной производственной ситуацией~. Таким образом, в нашем кластере задач по времени все еще есть функция, поддерживающая динамическую настройку~.

Последний ключевой компонент — балансировка нагрузки. Это очень важно! Поскольку это сделано неправильно, это может привести к тому, что несколько компьютеров будут конкурировать за одновременную обработку очереди, что повлияет на эффективность всего кластера! В случае ограниченного времени я использовал простой и практичный алгоритм, который использует Redis для увеличения ключа, а затем модифицирует количество очередей. Это в значительной степени гарантирует, что две машины не будут конкурировать за очередь в одно и то же время~.

Наконец, мы вычисляем пропускную способность всего кластера

10 (количество машин) * 2000 (количество рывков за раз) = 20000. Затем отправьте сообщение в центр сообщений в форме MQ. Отправка MQ является асинхронной, и для подсчета другой обработки требуется 0,5 с.

Фактически, отправка 20-ваттного push-уведомления занимает 10 секунд.

ok~ К этому моменту весь наш кластер запланированных задач почти приземлился. Если вы спросите меня, что еще я мог бы улучшить, это будет:

  • С мониторингом, как кластер может не иметь мониторинга, а если есть проблема и накопились задачи~

  • Плюс визуальный интерфейс.

  • Лучше иметь интеллектуальное планирование, чтобы повысить приоритет задач. Задачи с более высоким приоритетом будут выполняться первыми.

  • Планирование ресурсов, при недостаточном количестве машин и недостаточной мощности приоритет отдается обеспечению выполнения важных задач.

В настоящее время проект находится на переднем крае и работает без сбоев~.

Рекомендуемое чтение

Java Notes Daquan.md

Удивительно, на этом веб-сайте Java есть все виды проектов! https://markerhub.com

Мастер UP этой станции B, java действительно хорош!