Система уведомлений в социальных сетях

10

Фон

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

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

Со стороны пользовательского интерфейса у нас будет кнопка уведомления с номером на ней, и нажатие на кнопку приведет вас к экрану уведомлений.

Проблема

Я изучал стратегии реализации уведомлений, и большинство ресурсов, которые я нашел, указывают на создание одной или нескольких таблиц уведомлений в базе данных. (Примером, который мне нравится, является принятый ответ здесь: /programming/9735578/building-a-notification-system ).

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

Моя первоначальная идея заключалась в том, чтобы обрабатывать все с помощью запросов: число на кнопке уведомления будет получено путем запроса подсчета количества строк в содержимом, опубликованном более недавно, чем в последний раз, когда вы посещали экран уведомлений, тогда как индивидуальные уведомления будут генерироваться из более подробных запросов. когда вы посетили экран уведомлений. Этот подход не требует записи или дополнительного хранилища, но он негибкий и, вероятно, довольно сильно забьет сервер.

НАСТРОИТЬ

Бэкэнд (как было установлено предыдущим разработчиком) использует CodeIgniter и базу данных MySQL . В настоящее время он работает на дрянной учетной записи общего хостинга GoDaddy, но я предполагаю (надеюсь?), Что он будет обновлен до того, как мы начнем работу, и пакет хостинга будет масштабироваться с ростом пользователей.

В настоящее время нашим единственным интерфейсом является мобильное приложение, но мы планируем позже создать веб-сайт. В настоящее время я не заинтересован в получении в реальном времени push-обновлений с сервера об уведомлениях.

ДОПОЛНЕНИЕ

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

Я надеюсь, что это достаточно конкретная проблема, чтобы быть размещенной здесь; Я могу уточнить это, если это будет необходимо. Пожалуйста, спросите, если у вас есть какие-либо вопросы, или я пропустил важные детали.

ТЛ; др

  • Имеет ли система уведомлений, управляемая базой данных, негативные последствия для долгосрочной масштабируемости, когда все пользователи следуют только некоторым из тех же нескольких сотен человек?
  • Есть ли способ сделать базу данных уведомлений управляемой, не требуя отдельной строки уведомлений для каждого уведомления для каждого подписчика?
  • Будет ли система уведомлений, полностью управляемая запросами, масштабируемой или иметь какие-либо преимущества, кроме того, что не записывает какие-либо данные в БД?
  • Я слишком рано обдумываю это? Должен ли я просто создать что-то, что работает на данный момент, и мы можем беспокоиться об его оптимизации, если это станет проблемой, учитывая, что у клиента ограниченный бюджет, и мы пока не знаем, будет ли конечный продукт популярным?
user45623
источник
Вы можете истечь уведомления? Например, удалить что-нибудь старше 2 недель. Это должно более или менее сбалансировать размер таблицы, используемой по мере созревания сайта.
GrandmasterB
Это не будет проблемой, меня больше беспокоит влияние производительности на блокировку базы данных при записи 50 000 записей в таблицу уведомлений каждый раз, когда популярный пользователь делает сообщение.
user45623
Я работал над проектом с похожей (но меньшей) системой уведомлений. У меня был фоновый процесс, который просматривал очередь новых сообщений и обрабатывал уведомления (которые в данном случае фактически вставляли письмо во вторую очередь для отправки). Это было не в режиме реального времени, но обычно все обрабатывалось в течение пары минут.
GrandmasterB

Ответы:

10

Поэтому, если за Салли следуют тысячи человек, мы вставляем тысячу строк в соответствующую таблицу. Это масштабируемо?

Да, при условии, что таблицы базы данных правильно проиндексированы.

Что произойдет, если мы дойдем до того, что десятки или сотни тысяч пользователей следят за Салли, и она делает несколько десятков сообщений в день?

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

Моя первоначальная идея заключалась в том, чтобы обрабатывать все с помощью запросов: число на кнопке уведомления будет получено путем запроса подсчета количества строк в содержимом, опубликованном более недавно, чем в последний раз, когда вы посещали экран уведомлений, тогда как индивидуальные уведомления будут генерироваться из более подробных запросов. когда вы посетили экран уведомлений.

Это кажется излишне сложным. Если вам нужна подробная статистика об уведомлениях, просто сохраните уведомления.

Имеет ли система уведомлений, управляемая базой данных, негативные последствия для долгосрочной масштабируемости, когда все пользователи следуют только некоторым из тех же нескольких сотен человек?

Вот почему это работает ... небольшое количество людей всегда генерируют подавляющее большинство трафика.

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

Да ... Не храните уведомления; просто отправьте уведомления по электронной почте, в стиле «забей и забудь». Или сохраняйте уведомления в течение определенного периода времени, а затем отбрасывайте их. Или отмените каждое уведомление после его прочтения.

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

Я не уверен, что вы подразумеваете под этим. Если вы хотите запрашивать уведомления, вы должны хранить их в базе данных. В противном случае, нет ничего для запроса.

Я слишком рано обдумываю это?

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

Пример из жизни

Насколько я знаю, Stack Exchange хранит все на постоянной основе, включая все уведомления. Они используют технологию баз данных, аналогичную MySql, и некоторые технологии кэширования. Несмотря на то, что их оборудование и пространство для хранения значительны, объем трафика, который они получают, является хорошей проблемой.

Роберт Харви
источник
Вау, вы обратились к черту все! Спасибо, Роберт! База данных нормализована, но я еще не посмотрел на индексацию. К сожалению, я не могу «поговорить с кем-то, кто может мне помочь», поскольку условия жесткие, я не могу обсуждать конкретные детали проекта с кем-либо, и клиент дошел до того, что он никому не будет доверять но я на проекте ... Ну, я должен быть в состоянии сделать некоторые исследования по индексации. Спасибо!
user45623
1
Общие правила индексации: каждый внешний ключ должен быть проиндексирован с возможными дубликатами. Каждый первичный ключ уже должен быть проиндексирован. Поля, по которым вам нужно будет выполнить поиск или применить предложение WHERE, должны быть проиндексированы; таких должно быть мало.
Роберт Харви
1
Это неверно Это НЕ масштабируется. Для каждой «Салли» вы генерируете N строк, где N - ваше количество пользователей. Это быстро станет проблемой, если у вас будет какое-то разумное количество пользователей. 100 «Салли», которые 10 раз публикуют 10 000 пользователей, - это 10 миллионов строк в день - не слишком ли это хорошо, а? Что вы на самом деле хотите сделать, так это инвертировать это и создать по одной строке для каждой записи «Салли», чтобы все пользователи, следующие за Салли, брали их вместо своей личной копии. Конечно, это вызовет проблемы, если вам нужна пользовательская логика (например, агрегация) ...
Бен
1
... объяснение «избегать строки за пост» в данном случае, очевидно, соломенный человек, так как большинство систем требуют, чтобы эти посты оставались без присмотра. Кроме того, вы не избегаете запросов «потому что они сложные», вы избегаете их, потому что они вызовут неустойчивые накладные расходы по мере масштабирования системы.
Бен