システム設計面接:WhatsAppを設計する
「WhatsAppを設計せよ」は、大規模なリアルタイム配信、永続的なメッセージ保存、プレゼンス(オンライン/最終オンライン時刻)、そして数億台のデバイスを常時接続状態に保つという接続管理の問題を試します。いつものように、面接官が求めているのは実際のシステムのコピーではなく、あなたの推論とトレードオフです。
段階的に進めましょう:要件を明確にし、規模を見積もり、接続と配信の経路を設計し、メッセージの保存方法を決め、それからグループチャットやオフライン配信・順序保証といった難しい部分を扱います。以下のウォークスルーはこの流れに従います。
1. 要件を明確にする
まず範囲を固定します。中心となるのは信頼性の高い配信を伴う1対1のメッセージングです。グループチャット、メディア、エンドツーエンド暗号化がこの面接の範囲に含まれるかを確認しましょう。
- 機能要件:メッセージの送受信、配信済み・既読の通知、オンラインプレゼンス、グループチャット、受信者がオフラインの場合のオフライン配信。
- 非機能要件:低レイテンシ、高可用性、耐久性(メッセージの消失なし)、会話内での順序保証。
- 確認すべき点:E2E暗号化とメディアの取り扱い — 言及した上で、範囲に含めるかどうかを明示する。
2. 規模を見積もる
設計を導く数字を定めます。ユーザー数約20億人、1日に数百億件のメッセージがあると仮定すると、ピーク時には毎秒数十万件のメッセージ、そして数億台の端末が同時に接続していることになります。接続管理がそれ自体で一流の課題になります。
3. 接続と配信の経路
メッセージングには、リクエスト/レスポンスのポーリングではなく、持続的な接続が必要です。デバイスはゲートウェイサーバーへのWebSocketを開いたままにします。各ユーザーの接続を現在どのゲートウェイが保持しているかを中心的なコンポーネントが把握し、メッセージを正しいサーバーにルーティングできるようにする必要があります。
- WebSocketゲートウェイ:デバイスの生きた接続を維持し、送受信を処理する。
- セッション/プレゼンスレジストリ:ユーザーを現在のゲートウェイサーバーにマッピングする(例:Redis)。接続/切断時に更新される。
- メッセージルーティング:送信者側のゲートウェイが受信者側のゲートウェイを検索して転送する。受信者がオフラインの場合、メッセージはキューに入れられる。
4. メッセージの保存とオフライン配信
メッセージは受信者が切断されていても失われてはいけません。各メッセージを永続的に保存し、受信者ごとの配信状態を追跡します。受信者がオンラインであれば即座に配信し、そうでなければ保存して再接続時に転送します(ストア・アンド・フォワード)。
会話単位でキーを持つ、書き込みの多いアクセスパターンには、単一のリレーショナルDBよりもCassandraのようなワイドカラムストア(高い書き込みスループット、水平スケール)が適しています。すべての受信者への配信が確認されたメッセージは削除または期限切れにできます。WhatsAppは配信済みのメッセージをサーバー側で無期限に保持しないためです。
5. グループチャット
グループメッセージングはファンアウトです:1回の送信がN件の配信になります。一般的なグループサイズでは、ファンアウト・オン・ライト(各メンバーの配信経路にプッシュする)が単純で読み取りも高速です。注意点として、非常に大きなグループではファンアウト・オン・ライトのコストが高くなるため、巨大なブロードキャストグループは別の設計問題になります。
6. 言葉にすべきトレードオフ
最後に緊張関係を名指しします:順序保証(会話ごとのシーケンス番号 対 グローバルな順序)、確認応答における一貫性 対 可用性(「最終オンライン時刻」には結果整合性で十分だが、配信にはより強い保証が必要)、そしてグループにおけるファンアウト・オン・ライト 対 オン・リード。これらを明示的に指摘することが、シニアレベルの回答にする要素です。
リアルタイムサポートでWhatsAppのシステム設計を練習する
Nativelyのシステム設計面接アシスタントは、ライブの面接中にあなたを構造立てて支え、次に扱うべき観点を提案し、トレードオフをリアルタイムで表示します。すべて自分のデバイス上で完結します。
