私は最近、簡単な質問にうまく答えずに就職の面接を失敗させました:LinkedInのようなサイトは、ページに表示されるすべての人(たとえば、人の検索結果、働く人のリスト)までの関係距離(1st / 2nd / 3rd)をどのように効率的に表示しますか会社などで)?
<編集>私は解決策の本質的な「トリック」を手に入れました。「私からの距離」を見つけることは一般的な操作です(たとえば、1ページで20倍以上、ログインセッションごとに100)。 X "、それをキャッシュし、他の操作をはるかに安くするために、キャッシュされた部分的な結果を何度も再利用します。また、「すべての第3レベルの接続をキャッシュする」と、RAMとCPUのコストが高すぎるため、部分的な結果は第2レベルの接続になる可能性が高いと推測しました。</編集>
しかし、この洞察をソリューションに変換しようとすると、サイト上のすべての人の第2レベルの接続の永続的なキャッシュを作成するという厄介な答えを思いつきました(これは、パフォーマンスが非常に高く、維持するのが複雑でした)。技術的にほとんど意味をなさない方法でブルームフィルターを使用することへの不可解な迂回。そのような答えの後で私は自分自身を雇うことはなかっただろう!
後で、面接のプレッシャーを頭にかけずに問題について考えたとき、私はより合理的な答えを思いついた。
ユーザーIDのバッチごとに第1レベルの接続を取得するための非常に高速な方法を構築します(バッチサイズは最大1000?)。これはおそらく、ネットワーク全体の第1レベルの接続をメモリにキャッシュできる多数のRAMサーバーの専用クラスターを意味します。幸いなことに、5,000万人のメンバーx平均。メンバーあたり100接続xメンバーIDあたり4バイト=RAMにキャッシュするための<25GB。これは手頃な価格のハードウェアで実行できます。また、1日あたりの変更数は1%未満になるため、キャッシュを最新の状態に保つことはそれほど難しくありません。(「大量のランダムI / O」アクセスパターンはリレーショナルDBのパフォーマンスを低下させるため、リレーショナルデータベースはこのキャッシュを実装するのにおそらく悪い選択であることに注意してください。)
ユーザーがログインしたら、すべての第1レベル接続の第1レベル接続をフェッチして、第2レベル接続をキャッシュし、ハッシュテーブルに固定します(キー=第2レベルID、値=接続する第1レベル接続の配列)君)。また、第1レベルの接続もキャッシュして、リモートキャッシュサーバーへの1回のコールバックで第1レベルと第2レベルの両方をプルバックできるようにします。ユーザーIDは簡単にパーティション化できるため、memcachedのような分散キャッシュがこれに適している場合があります。
任意のユーザーIDについて、それが「ネットワーク」にあるかどうか、およびそれがユーザーとどのような関係にあるか(1番目、2番目、3番目)を確認するには、次のようにします。
- IDが第1レベルの接続にある場合は、停止します。
- キャッシュされた第2レベルの接続ハッシュテーブルでIDを検索してみてください。見つかった場合は、接続している接続の配列を返します。
- IDの第1レベルの接続をフェッチし、それぞれに対して手順2を繰り返します。すべての結果を1つの配列に集約し、それらを返します。
- <EDIT>をバッチ実装にリファクタリングして(「私からN人の異なるユーザーまでの距離を調べる」)、最大N個のリモート呼び出しを行うことなく、手順3のすべてのリモート結果を取得できます。</編集>
しかし、これにはもっと良い答えがあると確信しています。君は?さらに挑戦したい場合は、インタビューの状況をシミュレートしてみてください(Webでソリューションを検索することはできません)。
LinkedInが今日実際にどのようにそれを行っているかに関係なく、質問は最適な解決策に関するものであったことに注意してください。