[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Дубли в очереди
Страницы: 1, 2
Arh
Есть что то типа RabbitMQ, только с уникальными ключами?

Суть проблемы RabbitMQ:
Представим сайт с новостями, допустим хабрахабр.
Допустим он весь полностью кешируется.
Кешируется не по запросу пользователя, а программно.
Примерно так:
Пользователь добавил статью, страница добавилась в очередь на создание кеша.
Но по мимо страницы статьи также добавилась главная страница, страница с последними статьями, страница с разделом статьи, да и вообще все страницы, на которых она как то упоминается. В итоге допустим 5 уникальных страниц в очереди на добавление в кеш.

Теперь второй и третий и десятый пользователи тоже добавили статью в тот же раздел.
В очередь добавились ещё 10 страниц разных статей, 10 раз главная страница, 10 раз раздел, 10 раз страница с последними статьями и т.д.
В итоге в очереди вместо допустим 13 уникальных заданий, будет 50 дублей. (такая псевдо-математика)

С ходу видно два решения:
1) Делать всё на редисе. Туда нельзя записать больше одного элемента с одинаковым ключом, это как ассоциативный массив.
Но на него не повесить больше одного обработчика. Конечно если 50 дублей обрабатывают 5 обработчиков, то с 13 уникальными и один справится, но в случае чего это не расширить.
Есть вариант вешать каждый обработчик на свою маску ключа, типа один обрабатывает задачи по обновлению главной, другой страницы типа /page/*, третий третье. Но вдруг придут 50 пользователей и добавят 50 /page/* =)

2) Скрестить RabbitMQ и Redis.
При добавлении нового задания проверяется нет ли уже такого в Redis, если нет, в Redis добавляется ключ, а в RabbitMQ задача.
Когда RabbitMQ выполнит эту задачу, он удалит её из Redis.


В общем обожаю изобретать) Но скорее всего есть что то готовое? <- красным выделена суть вопроса

Что бы всю тему не читать:

Arh: Есть аналог RabbitMQ?
T1grOK: Разве что Kafka
Santehnick: Нету
Arh: ок, всем спасибо

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Гость_chee
Arh, Проблемы нет. Просто нужно обрабатывать все дубликаты в логике, а не на стороне транспорта сообщений.
Arh
Гость_chee
Есть проблема - дубли.
Цитата
Просто нужно обрабатывать все дубликаты в логике

Это я уже написал во втором решении.
А хотелось бы что то типа RabbitMQ, но с ключами.

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Гость_chee
Arh, ты не правильно понял мои слова. Я имел ввиду что не на уровне radis не на уровне rabbitmq не надо решать проблему дублирования сообщений, это нужно делать непосредственно в консьюмере. Консьюмер должен проверять сообщение, было ли подобное сообщение обработано другим или этим же консьюмером.
Гость_chee
Если сообщение уже было обработано другим консьюмером, говорить очереди что сообщение обработано, но по факту ничего не делать.
Arh
Гость_chee
Цитата
было ли подобное сообщение обработано другим или этим же консьюмером

А как он узнает, что подобное сообщение было обработано?

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Гость_chee
Ну заведи таблицу в которой будешь хранить обработанные идентификаторы сообщений, перед началом выполнения логики консумера проверь существует ли такой идентификатор из сообщения в этой таблице.
Arh
Гость_chee
Цитата
Ну заведи таблицу в которой будешь хранить обработанные идентификаторы сообщений, перед началом выполнения логики консумера проверь существует ли такой идентификатор из сообщения в этой таблице.

Таблицу? В базе данных?
Ну он существует, потому что перед этим уже обрабатывался другим обработчиком, или этим же но вчера/минуту назад.
Зачем в базе, если можно в редисе?
Зачем писать дубли, а потом искать кто и когда их обрабатывал?
Перечитай решение пункт 2.


_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
T1grOK
Можно хранить в Redis счетчики, а на консюмере сравнивать значение счетчика из задачи и из Redis, тем самым будет обеспечено выполнение наиболее новой задачи. А на случай, если пользователи начнут долго и непрерывно, что-то добавлять, можно установить некоторый таймаут(время последнего выполнения, которое храним рядом с каждым счетчиком), при котором задание будет выполнено несмотря на значения счетчиков.

P.S. В целом, по теме, сложилось впечатление преждевременной оптимизации.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
Гость_chee
Arh, окей, сейчас понял. Ну можешь хранить в редисе, если ты его юзаешь в консьюмером, а не в логике самой очереди.
Arh
T1grOK
Цитата
P.S. В целом, по теме, сложилось впечатление преждевременной оптимизации.

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

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

Без RabbitMQ? На редис не повесить несколько обработчиков без адских костылей)

Цитата
А на случай, если пользователи начнут долго и непрерывно, что-то добавлять, можно установить некоторый таймаут

Не, если добавили, это должно появится сейчас, а не завтра, для этого и делают много обработчиков, что бы оперативно всё разгребать.

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

Так и есть.
Смотри. Консьюмер сейчас занят обновлением кеша какой то страницы.
Пользователь за это время взял свою статью и 10 раз поправил.
В очередь прилетело 10 задач на обновление кеша этой страницы.
Консьюмер взял первую задачу и обновил кеш. Всё кеш новый, сайт работает.
Но в очереди ещё 9 задач на обновление этой страницы, хотя она уже обновилась.

Цитата
И на сайте типа хабра кешировать полностью страницы не получится. Как минимум гость хочет видеть кнопку входа, пользователь кнопку выхода. Лучше закешировать запрос с выборкой последних статей из базы. По этому кешу потом можно будет любую из перечисленных страниц собрать.

Можно всё закешировать, а блок с входом/выходом сделать динамический с помощью nginx или ajax.
Но у меня нет входа/выхода.

Цитата
Лучше закешировать запрос с выборкой последних статей из базы.

А вообще этого тоже никто не отменял, только это внутренний кеш. Кеш бэкэнд сервера, но это уже совсем другая история)

Гость_chee
Цитата
Arh, окей, сейчас понял. Ну можешь хранить в редисе, если ты его юзаешь в консьюмером, а не в логике самой очереди.

А в чём профит? Зачем обработчику лишний геморрой?
Если спроэкцировать на другой пример, то у тебя получается что пользователи при сохранении новости делают insert в базу, а потом мы заморачиваемся как бы выводить только одну статью, а не 10 одинаковых.
Хотя можно сделать insert update и избавить обработчик от геморроя.

Надо твина призвать, что бы он нашёл тему, где были рекомендации по ответам на форуме. Типа сообщение должно отвечать на вопрос "почему?")

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.