TL; DR:
Używają architektury stosu z buforowanymi wykresami dla wszystkiego, co znajduje się powyżej dolnej części stosu MySQL.
Długa odpowiedź:
Zrobiłem kilka badań na ten temat, ponieważ byłem ciekawy, jak radzą sobie z ogromną ilością danych i przeszukują je w szybki sposób. Widziałem ludzi narzekających, że niestandardowe skrypty sieci społecznościowych zwalniają, gdy rośnie liczba użytkowników. Po przeprowadzeniu testów porównawczych z zaledwie 10 tysiącami użytkowników i 2,5 milionami połączeń znajomych - nawet nie próbując zawracać sobie głowy uprawnieniami grupowymi, polubieniami i wpisami na ścianie - szybko okazało się, że to podejście jest wadliwe. Spędziłem więc trochę czasu na przeszukiwaniu sieci i zastanawiałem się, jak to zrobić lepiej, i trafiłem na ten oficjalny artykuł na Facebooku:
I naprawdę polecam do obejrzenia prezentacji pierwszego linku powyżej przed kontynuować czytanie. To prawdopodobnie najlepsze wyjaśnienie, jak działa FB za kulisami, jakie można znaleźć.
Film i artykuł mówią ci o kilku rzeczach:
- Używają MySQL na samym dole swojego stosu
- Nad bazą danych SQL znajduje się warstwa TAO, która zawiera co najmniej dwa poziomy buforowania i używa wykresów do opisu połączeń.
- Nie mogłem znaleźć niczego na temat oprogramowania / bazy danych, której faktycznie używają do swoich buforowanych wykresów
Rzućmy okiem na to, połączenia znajomych są u góry po lewej:
Cóż, to jest wykres. :) Nie mówi ci, jak zbudować to w SQL, jest na to kilka sposobów, ale ta strona ma wiele różnych podejść. Uwaga: Weź pod uwagę, że relacyjna baza danych jest tym, czym jest: uważa się, że przechowuje znormalizowane dane, a nie strukturę wykresu. Więc nie będzie działać tak dobrze, jak wyspecjalizowana baza danych grafów.
Weź również pod uwagę, że musisz wykonywać bardziej złożone zapytania niż tylko znajomi znajomych, na przykład gdy chcesz odfiltrować wszystkie lokalizacje wokół danej współrzędnej, które lubisz ty i twoi znajomi znajomych. Wykres jest tutaj idealnym rozwiązaniem.
Nie mogę ci powiedzieć, jak go zbudować, aby działał dobrze, ale najwyraźniej wymaga to kilku prób i błędów oraz testów porównawczych.
Oto mój rozczarowujący test tylko dla znalezisk przyjaciół znajomych:
Schemat bazy danych:
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;
Zapytanie o znajomych znajomych:
(
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
)
Naprawdę zalecam utworzenie przykładowych danych z co najmniej 10 tys. Rekordów użytkowników, z których każdy ma co najmniej 250 połączeń znajomych, a następnie uruchomienie tego zapytania. Na moim komputerze (i7 4770k, SSD, 16GB RAM) wynik dla tego zapytania wyniósł ~ 0,18 sekundy . Może da się to zoptymalizować, nie jestem geniuszem DB (sugestie są mile widziane). Jednakże, jeśli ten Wagi liniowe jesteś już w 1,8 sekundy za jedyne 100k użytkowników, 18 sekund do 1 miliona użytkowników.
Może to nadal brzmieć OK dla ~ 100 000 użytkowników, ale weź pod uwagę, że właśnie pobrałeś znajomych znajomych i nie wykonałeś żadnego bardziej złożonego zapytania, takiego jak „ wyświetlaj mi tylko posty od znajomych znajomych + sprawdź uprawnienia, czy mam pozwolenie czy NIE aby zobaczyć niektóre z nich + wykonaj zapytanie podrzędne, aby sprawdzić, czy któryś mi się podobał ". Chcesz pozwolić DB sprawdzać, czy już polubiłeś post, czy nie, albo będziesz musiał to zrobić w kodzie. Weź również pod uwagę, że nie jest to jedyne zapytanie, które uruchamiasz i że masz jednocześnie więcej niż aktywnych użytkowników w mniej lub bardziej popularnej witrynie.
Myślę, że moja odpowiedź odpowiada na pytanie, w jaki sposób Facebook bardzo dobrze zaprojektował relacje z przyjaciółmi, ale przykro mi, że nie mogę powiedzieć, jak to zaimplementować, aby działało szybko. Wdrożenie sieci społecznościowej jest łatwe, ale upewnienie się, że działa dobrze, zdecydowanie nie jest - IMHO.
Zacząłem eksperymentować z OrientDB w celu wykonywania zapytań grafowych i mapowania moich krawędzi do podstawowej bazy danych SQL. Jeśli kiedykolwiek to zrobię, napiszę o tym artykuł.