Реализация фида событий - будет ли он масштабироваться? - PullRequest
5 голосов
/ 17 мая 2010

Положение:

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

События от всех пользователей собираются в одну центральную таблицу базы данных, event_log. Пользователи в паре как друзья в таблице friends. СУБД, которую мы используем, - MySQL.

Стандартный метод: Когда пользователь запрашивает свою страницу канала, система генерирует канал путем внутреннего соединения event_log с friends. Затем результат кэшируется и устанавливается на тайм-аут через 5 минут. Масштабирование достигается путем изменения этого времени ожидания.

Гипотетический метод: Задача выполняется в фоновом режиме, и для каждого нового необработанного элемента в event_log она создает записи в таблице базы данных user_feed, связывающие это событие со всеми пользователями, которые являются друзьями с пользователем, инициировавшим событие. Одна строка таблицы связывает одно событие с одним пользователем.

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

Предполагаемое решение в моих глазах кажется намного лучше; вся обработка выполняется в автономном режиме, поэтому ни один пользователь не ожидает создания страницы, и нет никаких объединений, поэтому таблицы базы данных могут быть распределены между физическими машинами. Однако если пользователь имеет 100 000 друзей и создает 20 событий в одном сеансе, это приводит к вставке 2 000 000 строк в базу данных.

Вопрос:

Вопрос сводится к двум пунктам:

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

Ответы [ 2 ]

1 голос
/ 18 мая 2010

Я думаю, что ваша предполагаемая система генерирует слишком много данных; во-первых, в глобальном масштабе требования к хранилищу и индексированию для user_feed, по-видимому, возрастают экспоненциально, поскольку ваша пользовательская база становится больше и более взаимосвязанной (и то, и другое, по-видимому, желательно для социальной сети); во-вторых, подумайте, если в течение одной минуты каждое 1000 пользователей вводило новое сообщение и у каждого было 100 друзей, - тогда ваш фоновый поток должен сделать 100 000 вставок и может быстро отстать.

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

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

0 голосов
/ 25 июля 2010

Метод Hypothesized работает лучше, когда вы ограничиваете максимальное количество друзей. Многие сайты устанавливают безопасную верхнюю границу, включая Facebook iirc. Это ограничивает «икоты» с того момента, когда ваш пользователь из 100K друзей создает активность.

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

Я много раз думал об этой проблеме - это не проблема, которую MySQL решит хорошо. Я подумал о том, как использовать memcached, и каждый пользователь помещает свои последние несколько статусных элементов в «свой ключ» (а в процессе чтения фида вы получаете и собираете все ключи вашего друга) ... но я не проверил это. Я не уверен во всех плюсах / минусах.

...