TL; DR:
Они используют стековую архитектуру с кэшированными графами для всего, что находится выше нижней части стека MySQL.
Длинный ответ:
Я сам провел небольшое исследование по этому поводу, потому что мне было любопытно, как они обрабатывают свои огромные объемы данных и быстро их ищут. Я видел, как люди жаловались на то, что скрипты социальных сетей, созданные по индивидуальному заказу, замедляются при росте пользовательской базы. После того, как я провел несколько тестов с участием всего 10 тыс. Пользователей и 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 тыс. Пользователей и 18 секунд для 1 миллиона пользователей.
Это может показаться нормальным для ~ 100 тыс. Пользователей, но учтите, что вы только что пригласили друзей друзей и не выполняли более сложный запрос вроде « отображать мне только сообщения от друзей друзей + проверять разрешения, разрешено ли мне или НЕ разрешено. чтобы увидеть некоторые из них + выполните дополнительный запрос, чтобы проверить, понравился ли мне какой-либо из них ». Вы хотите, чтобы база данных провела проверку, понравился ли вам пост или нет, или вам придется делать это в коде. Также учтите, что это не единственный запрос, который вы выполняете, и что у вас есть более чем активных пользователей одновременно на более или менее популярном сайте.
Я думаю, что мой ответ отвечает на вопрос, как Facebook очень хорошо спланировал отношения с друзьями, но мне жаль, что я не могу сказать вам, как реализовать это так, чтобы это работало быстро. Внедрить социальную сеть легко, но убедиться, что она работает хорошо, явно не так - ИМХО.
Я начал экспериментировать с OrientDB, чтобы выполнять графические запросы и отображать мои ребра в базовую базу данных SQL. Если у меня это получится, я напишу об этом статью.