Я нахожусь в начале создания системы уведомлений в стиле Facebook для нашей страницы (типа социальных игр), и сейчас я изучаю, как лучше всего разработать такую систему. Меня не интересует, как отправлять уведомления пользователю или что-то в этом роде (на данный момент даже). Я изучаю, как построить систему на сервере (как хранить уведомления, где хранить их, как получать их и т.д. ...).
Итак ... некоторые требования, которые у нас есть:
- в пиковое время у нас есть около 1k одновременно зарегистрированных пользователей (и еще много гостей, но здесь они не имеют значения, так как у них не будет уведомлений), которые будут генерировать много событий
- будут различные типы уведомлений (пользователь A добавил вас в друзья, пользователь B прокомментировал ваш профиль, пользователю C понравилось ваше изображение, пользователь D избил вас в игре X, ...)
- большинство событий генерируют 1 уведомление для 1 пользователя (пользователю X понравилось ваше изображение), но будут случаи, когда одно событие будет генерировать много уведомлений (например, это день рождения пользователя Y)
- уведомления должны быть сгруппированы вместе; если, например, четыре разных пользователя любят какое-то изображение, владелец этого изображения должен получить одно уведомление о том, что изображение понравилось четырем пользователям, а не четырем отдельным уведомлениям (как FB)
Итак, я подумал, что мне нужно создать какую-то очередь, где я буду хранить события, когда они происходят. Тогда у меня будет фоновая работа ( gearman ?), Которая будет просматривать эту очередь и генерировать уведомления на основе этих событий. Затем это задание будет хранить уведомления в базе данных для каждого пользователя (поэтому, если событие затрагивает 10 пользователей, будет 10 отдельных уведомлений). Затем, когда пользователь открывал страницу со списком уведомлений, я читал все эти уведомления для него (мы надеемся ограничить это до 100 последних уведомлений) и группировал их вместе, а затем, наконец, отображал их.
Что меня беспокоит в этом подходе:
- сложный как черт :)
- Является ли база данных лучшим хранилищем здесь (мы используем MySQL) или я должен использовать что-то еще (redis тоже кажется подходящим)
- что я должен хранить как уведомление? идентификатор пользователя, идентификатор пользователя, который инициировал событие, тип события (чтобы я мог сгруппировать их и отобразить соответствующий текст), но тогда я вроде не знаю, как хранить фактические данные уведомления (например, URL-адрес и заголовок изображения, которое было понравилось). Должен ли я просто «испечь» эту информацию при создании уведомления или сохранить идентификатор затрагиваемой записи (изображение, профиль, ...) и извлечь информацию из БД при отображении уведомления.
- производительность должна быть в порядке, даже если мне нужно обрабатывать 100 уведомлений на лету при отображении страницы уведомлений
- возможная проблема с производительностью при каждом запросе, потому что мне пришлось бы отображать количество непрочитанных уведомлений для пользователя (что само по себе может быть проблемой, поскольку я собирал уведомления вместе). Этого можно избежать, если бы я генерировал представление уведомлений (где они сгруппированы) в фоновом режиме, а не на лету
Так что вы думаете о моем предложенном решении и моих проблемах? Пожалуйста, прокомментируйте, если вы считаете, что я должен упомянуть что-либо еще, что будет иметь отношение к делу.
О, мы используем PHP для нашей страницы, но это не должно быть большим фактором здесь, я думаю.