TL; DR:
Они используют стековую архитектуру с кэшированными графами для всего, что находится выше MySQL в нижней части их стека.
Длинный ответ:
Я сам провел некоторые исследования по этому вопросу, потому что мне было любопытно, как они обрабатывают свои огромные объемы данных и быстро их ищут. Я видел людей, жалующихся на то, что пользовательские скрипты в социальных сетях становятся медленными по мере роста базы пользователей. После того, как я провел сравнительный анализ с только 10k пользователями и 2,5 миллионами друзей подключений - даже не пытаясь беспокоиться о групповых разрешениях и лайках и постах на стене - быстро оказалось, что этот подход недостатки. Поэтому я потратил некоторое время на поиск в Интернете, как это сделать лучше, и наткнулся на эту официальную статью в Facebook:
Я действительно рекомендую вам посмотреть презентацию по первой ссылке выше, прежде чем продолжить чтение. Это, вероятно, лучшее объяснение того, как FB работает за кулисами, вы можете найти.
Видео и статья рассказывают вам несколько вещей:
- Они используют MySQL в самом низе своего стека
- Выше базы данных SQL находится слой TAO, который содержит как минимум два уровня кэширования и использует графики для описания соединений.
- Я не смог найти ничего о том, какое программное обеспечение / БД они фактически используют для своих кэшированных графиков
Давайте посмотрим на это, дружеские связи вверху слева:
Ну, это график. :) Он не говорит вам , как построить его в SQL, есть несколько способов сделать это, но этот сайт имеет множество различных подходов. Внимание: Учтите, что реляционная БД - это то, чем она является: считается, что она хранит нормализованные данные, а не структуру графа. Так что он не будет работать так же хорошо, как специализированная графовая база данных.
Также учтите, что вам нужно выполнять более сложные запросы, чем просто друзья друзей, например, когда вы хотите отфильтровать все местоположения вокруг заданной координаты, которые нравятся вам и вашим друзьям друзей. График является идеальным решением здесь.
Я не могу сказать вам, как построить его так, чтобы он работал хорошо, но он явно требует проб и ошибок и тестирования.
Вот мой разочаровывающий тест для просто находок друзей друзей:
Схема БД:
CREATE TABLE IF NOT EXISTS `friends` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`friend_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Запрос друзей друзей:
(
select friend_id
from friends
where user_id = 1
) union (
select distinct ff.friend_id
from
friends f
join friends ff on ff.user_id = f.friend_id
where f.user_id = 1
)
Я действительно рекомендую вам создать пример данных с минимум 10 тысячами пользовательских записей, каждая из которых имеет как минимум 250 дружеских соединений, а затем выполнить этот запрос. На моей машине (i7 4770k, SSD, 16 ГБ ОЗУ) результат запроса составил ~ 0,18 секунды . Может быть, это можно оптимизировать, я не гений БД (предложения приветствуются). Тем не менее, , если это линейное масштабирование, вы уже на 1,8 секунды для всего 100 000 пользователей, 18 секунд для 1 миллиона пользователей.
Это может звучать нормально для пользователей ~ 100k, но учтите, что вы только что выбрали друзей друзей и не сделали более сложный запрос, например ", отображать только сообщения от друзей друзей + проверять разрешение, если я мне разрешено или НЕ разрешено видеть некоторые из них + сделать подзапрос, чтобы проверить, понравился ли мне какой-либо из них". Вы хотите, чтобы БД проверила, понравился ли вам пост или нет, или вам придется делать это в коде. Также учтите, что это не единственный запрос, который вы выполняете, и у вас есть более чем активный пользователь одновременно на более или менее популярном сайте.
Я думаю, что мой ответ отвечает на вопрос, как Facebook очень хорошо спроектировал отношения с друзьями, но мне жаль, что я не могу рассказать вам, как реализовать это так, чтобы это работало быстро. Внедрить социальную сеть легко, но убедиться, что она работает хорошо, явно нет - ИМХО.
Я начал экспериментировать с OrientDB, чтобы выполнять граф-запросы и отображать свои ребра в базовую базу данных SQL. Если я когда-нибудь это сделаю, я напишу об этом статью.