Положение:
В настоящее время я разрабатываю систему каналов для социального сайта, в которой каждый пользователь получает ленту действий своих друзей. У меня есть два возможных способа создания каналов, и я хотел бы спросить, какой из них лучше всего подходит для масштабирования.
События от всех пользователей собираются в одну центральную таблицу базы данных, event_log
. Пользователи в паре как друзья в таблице friends
. СУБД, которую мы используем, - MySQL.
Стандартный метод:
Когда пользователь запрашивает свою страницу канала, система генерирует канал путем внутреннего соединения event_log
с friends
. Затем результат кэшируется и устанавливается на тайм-аут через 5 минут. Масштабирование достигается путем изменения этого времени ожидания.
Гипотетический метод:
Задача выполняется в фоновом режиме, и для каждого нового необработанного элемента в event_log
она создает записи в таблице базы данных user_feed
, связывающие это событие со всеми пользователями, которые являются друзьями с пользователем, инициировавшим событие. Одна строка таблицы связывает одно событие с одним пользователем.
Проблемы со стандартным методом хорошо известны - что, если у многих из них одновременно истекает кеш? Решение также не очень хорошо масштабируется - кратко, чтобы каналы обновлялись как можно ближе к реальному времени
Предполагаемое решение в моих глазах кажется намного лучше; вся обработка выполняется в автономном режиме, поэтому ни один пользователь не ожидает создания страницы, и нет никаких объединений, поэтому таблицы базы данных могут быть распределены между физическими машинами. Однако если пользователь имеет 100 000 друзей и создает 20 событий в одном сеансе, это приводит к вставке 2 000 000 строк в базу данных.
Вопрос:
Вопрос сводится к двум пунктам:
- Проблематичен ли этот наихудший сценарий, упомянутый выше, т.е. влияет ли размер таблицы на производительность MySQL и есть ли проблемы с этой массовой вставкой данных для каждого события?
- Есть что-то еще, что я пропустил?