TL; DR:
彼らは、スタックのMySQLの最上位より上のすべてに対して、キャッシュされたグラフを備えたスタックアーキテクチャを使用します。
長い答え:
彼らが膨大な量のデータをどのように処理し、すばやく検索するのか知りたくて、自分でこれについていくつかの調査を行いました。ユーザーベースが拡大すると、カスタムメイドのソーシャルネットワークスクリプトが遅くなることについて不満を言う人を見てきました。たった1万人のユーザーと250万人の友達の接続でベンチマークを行ったところ、グループのアクセス許可といいね!と壁の投稿にさえ気を取らなかった後、すぐにこのアプローチに欠陥があることがわかりました。それで、私はそれをより良くする方法についてウェブを検索することに時間を費やして、この公式のFacebookの記事に出くわしました:
私は本当に前に読み続ける上で最初のリンクのプレゼンテーションを見てすることをお勧めいたします。これはおそらく、FBがバックグラウンドでどのように機能するかを説明する最良の説明です。
ビデオと記事はあなたにいくつかのことを教えています:
- スタックの最下部でMySQLを使用している
- SQL DBの上には、少なくとも2つのレベルのキャッシングを含み、グラフを使用して接続を記述するTAOレイヤーがあります。
- キャッシュされたグラフに実際に使用しているソフトウェア/ DBについては何も見つかりませんでした
これを見てみましょう。友達の接続は左上です。
さて、これはグラフです。:)それはSQLでそれを構築する方法を教えてくれません、それを行うにはいくつかの方法がありますが、このサイトにはかなりの量の異なるアプローチがあります。注意:リレーショナルDBがそれであると考えてください:グラフ構造ではなく、正規化されたデータを格納すると考えられています。そのため、特殊なグラフデータベースほどパフォーマンスが良くありません。
また、たとえば、自分と友達の友達が好きな特定の座標の周りのすべての場所をフィルタリングする場合など、友達の友達よりも複雑なクエリを実行する必要があることも考慮してください。ここではグラフが最適なソリューションです。
うまく機能するようにビルドする方法は説明できませんが、明らかに試行錯誤とベンチマークが必要です。
友達の友達を見つけただけの私の残念なテストは次のとおりです。
DBスキーマ:
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;
Friends of Friendsクエリ:
(
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
)
少なくとも1万のユーザーレコードと、それぞれに少なくとも250のフレンド接続を持つサンプルデータを作成してから、このクエリを実行することをお勧めします。私のマシン(i7 4770k、SSD、16GB RAM)では、そのクエリの結果は〜0.18 秒でした。多分それは最適化できるかもしれません、私はDBの天才ではありません(提案は大歓迎です)。ただし、これが線形に拡張された場合、ユーザーは10万人で1.8秒、100万人で18秒です。
これはまだ10万人までのユーザーには問題ないように聞こえるかもしれませんが、友達の友達を取得しただけで、「友達の友達からの投稿のみを表示する+許可されているか許可されていない場合は許可チェックを行う」などの複雑なクエリを実行しなかったことを考慮してくださいそれらのいくつかを確認するには、サブクエリを実行して、それらのいずれかが気に入ったかどうかを確認します。投稿が気に入ったかどうか、またはコードで行う必要があるかどうかをDBにチェックさせたいとします。また、これが実行する唯一のクエリではなく、多かれ少なかれ人気のあるサイトで同時にアクティブユーザー以上のユーザーがいることも考慮してください。
私の回答は、Facebookがどのように友人関係をうまく設計したかという質問に答えると思いますが、それが高速に機能するように実装する方法を説明できないのは残念です。ソーシャルネットワークの実装は簡単ですが、それがうまく機能することを確認することは明らかにそうではありません-私見。
グラフクエリを行うためにOrientDBの実験を開始し、基になるSQL DBにエッジをマッピングしました。もし私がそれを成し遂げたら、それについての記事を書きます。