代表的な面接トピック

システムデザイン面接:リアルタイムチャットシステムをどう設計するか?

システム設計難しい
Offer.cc 編集チーム公開日 更新日

質問

日間アクティブユーザー5,000万人、ピーク時同時接続数500万、1日あたり20億メッセージを処理するテキストチャットシステムを設計してください。1対1の会話、最大200人のグループ、複数デバイス、オフライン時のキャッチアップ、配信・既読確認、プレゼンス、入力中表示をサポートする必要があります。受理されたメッセージがサイレントに消失してはならず、通常負荷時のオンライン配信p99は1秒未満を維持する必要があります。プロトコル、API、ストレージ、順序付け、冪等性、ファンアウト、再接続、キャパシティ、障害耐性、セキュリティ、検証について説明してください。

プロンプトと適用コンテキスト

日間アクティブユーザー5,000万人、ピーク時同時接続数500万、1日あたり20億メッセージを処理するテキストチャットサービスを設計します。ダイレクトメッセージ、最大200人のグループ、ユーザーごとの複数デバイス、オフラインキャッチアップ、配信・既読確認、プレゼンス、入力中表示をサポートします。添付ファイル、パブリックチャンネル、クロスリージョンのアクティブ・アクティブ書き込み、全文検索、エンドツーエンド暗号化はフォローアップの対象とします。

このサービスは、メッセージが永続的に保存された後にのみ送信確認(ACK)を返します。受理されたメッセージをサイレントに失ってはなりません。通常負荷下で既にオンラインである受信者に対しては、永続的な受付から接続されたデバイスへの到達までのp99が1秒未満である必要があります。トランスポート層で再配信が発生する可能性があるため、クライアントは重複排除後に論理的に1つのメッセージとして認識しなければなりません。順序付けは単一の会話内で必要とされ、無関係な会話をまたぐ順序付けは不要です。

2026年に公開または改訂された3つの公開システムデザインガイドでは、チャットが面接の直接的な課題として取り上げられており、永続接続、接続ルーティング、会話ごとの順序付け、オフライン同期、レシート、プレゼンスが繰り返し検証されています。WebSocket標準が双方向トランスポートと制御フレームを定義し、Matrixのクライアント・サーバー仕様はクライアントトランザクションID、増分同期トークン、既読レシート、エフェメラルなタイピングイベントの本番レベルの実装例を提供しています。これらのソースは、このトピックと障害境界が現代的かつ技術的に確固たるものであることを示しています。本プロンプトの規模とSLOは面接用の架空の入力値です。

面接官が評価するポイント

第1の評価ポイントは、コントラクトの厳密さです。「送信済み」「配信済み」「既読」はそれぞれ異なる事実です。サーバーの確認応答は永続的な受付を意味します。配信レシートは、特定の受信デバイスがメッセージを受信したことを意味します。既読レシートには、ユーザーが実際にその会話を表示したという明示的な製品ルールが必要です。これら3つを単一の状態として扱うと、信頼性の誤認や不正確な未読カウントが発生します。

第2の評価ポイントは、候補者がエンドツーエンドでの「厳密に1回(exactly-once)」の保証を避けているかどうかです。クライアントは、サーバーがコミットした後、ACKが届く前にタイムアウトする可能性があります。ゲートウェイは再接続後に配信を繰り返す可能性があります。実用的なコントラクトは、「少なくとも1回(at-least-once)」のトランスポートに、安定したクライアントメッセージID、サーバー側の冪等性レコード、およびサーバーメッセージIDによるクライアント側の重複排除を組み合わせることです。

第3の評価ポイントは、順序付けの境界です。グローバルな順序付けを行うと、無関係な会話まで直列化されてしまいます。実用的な製品コントラクトでは、受理された各メッセージに会話内での単調増加シーケンスを付与します。したがって、1つの会話に対するすべての書き込みは、現在の1つのオーナーまたはシーケンサーに到達します。これにより、ローカルな順序を維持しながら異なる会話を独立してスケールさせることができ、トラフィックが集中するホットな会話の現実的な制限が明確になります。

第4の評価ポイントは、永続状態とエフェメラル(一時的)な状態の分離です。メッセージ、メンバーシップの期間、既読カーソルは障害発生後も保持される必要があります。一方、プレゼンスや入力中表示は期限切れに伴い破棄できます。タイピングトラフィックを永続メッセージログと共有させると、ストレージが無駄になり、一時的なバーストによって実際のメッセージ配信が遅延する原因になります。

最後の評価ポイントは、リカバリに関する思考力です。送信ACKの消失、ゲートウェイの障害、再接続ストーム、古い会話オーナー、低速デバイス、メンバーシップの変更、重複ファンアウト、トラフィックが集中したグループへの対応が含まれている必要があります。キャパシティの数値はプロンプトから論理的に導き出され、普遍的なサーバーの限界として提示するのではなく、負荷テストによって調整されるべきです。

回答前に明確にすべき質問

  • 対象となるコンテンツと会話のタイプは何か? 本回答ではテキスト、ダイレクトメッセージ、最大200人のグループを扱います。添付ファイルにはオブジェクトストレージとメタデータメッセージを使用し、パブリックチャンネルには異なるファンアウトおよび履歴戦略が必要です。
  • 各レシートは何を意味するか? 「サーバー受理」「デバイス受信」「ユーザー既読」は別個の単調な事実です。「既読」は、単にプッシュ通知を受信した時ではなく、クライアントが該当する会話を実際に画面表示した時にのみ発生します。
  • どのような順序付けが必要か? プロンプトでは会話ごとの安定した順序が求められています。ユーザーの端末時計が順序を決定することや、異なる2つの会話が1つのシーケンスを共有することは保証しません。
  • ユーザーは複数デバイスから送信できるか? はい。各デバイスは独自の認証済み接続と同期カーソルを持ち、送信者の再試行時は同じクライアントメッセージIDを再利用します。
  • メンバーシップが変更された場合はどうなるか? 認可はメッセージ受付時にチェックされます。新規メンバーが過去の履歴を閲覧できるか、削除されたメンバーがローカルに何を保持できるかは製品仕様として定義する必要があります。本設計では、会話シーケンス番号に基づくメンバーシップ有効期間を保存します。
  • メッセージと冪等性レコードの保持期間はどのくらいか? メッセージの保持期間は製品およびコンプライアンスの決定事項です。冪等性マッピングはクライアントの最大再試行ウィンドウをカバーする必要があり、それより早く削除すると重複が発生するリスクがあります。
  • どのリージョンを使用するか? 基本設計では各会話にホームリージョンを割り当て、計画的にフェイルオーバーさせます。複数リージョンでの同時書き込み可能なレプリカは、より複雑な競合解決および順序付けモデルを必要とします。
  • 1秒の目標対象外となるものは何か? オフラインプッシュの表示、再接続時のキャッチアップ、ユーザーの既読操作までの時間、クロスリージョンのディザスタリカバリは、既に接続されているデバイスへのリアルタイム配信とは個別に測定されます。

30秒の回答フレームワーク

「接続管理を永続メッセージ経路から分離します。クライアントは、安定したクライアントメッセージIDを用いて認証済みWebSocket経由で送信します。会話ごとにルーティングされたサービスがメンバーシップを再確認し、会話ごとの次のシーケンス番号を割り当て、メッセージと冪等性結果をアトミックに保存した後に初めてACKを返します。非同期のファンアウトワーカーがアクティブな受信デバイスを検索して各ゲートウェイに送信し、オフラインまたは障害の発生したデバイスはカーソルベースの同期APIから復旧します。配信および既読カーソルは単調増加し、プレゼンスと入力中表示は別系統の有効期限付き経路を使用します。トランスポートは少なくとも1回(at-least-once)であるため、サーバーとクライアントの双方が重複排除を行います。提示された規模に基づき、平均で毎秒約23,000件、ピーク時で毎秒約230,000件の送信、1件あたり1KBとして1日約2TBの論理メッセージデータを想定し、永続接続、ホットなグループ、再接続ストーム、再試行、メンバーシップ変更、オーナーのフェイルオーバーをSLOに対して負荷テストします。」

ステップごとの詳細解説

ステップ1:製品コントラクトを確定し、初期のキャパシティ見積もりを算出する。

1日20億件のメッセージは、平均で毎秒約23,148件の送信に相当します。ピークが平均の10倍と仮定すると、インgress設計は毎秒約230,000件の送信から検討します。通常のメタデータやインデックスを含めて保存メッセージ1件あたり1KBと仮定すると、論理書き込み量は1日あたり約2TBとなります。3レプリカ構成の場合、コンパクション、ファイルシステム予約領域、バックアップ、レシート書き込みを除いて1日約6TBとなります。これらは計画上の前提であり、実測されたハードウェア限界ではありません。

ゲートウェイのサイジングは、500万の同時接続数が支配的な要因となります。選択したインスタンス、TLS設定、ハートビート間隔、目標p99における負荷テストで、ゲートウェイ1台あたり50,000件の健全な接続が維持できると実証されたと仮定します。必要最小限の台数は100台です。その測定限界の70%で運用する場合、約143台(切り上げて150台)に加えてゾーン障害用の予備が必要となります。テストにはメッセージ送受信、再接続、低速クライアントを含める必要があり、アイドル状態のソケット数のみで判断すると誤った設計になります。

ステップ2:クライアントプロトコルとその識別子を定義する。

すべてのデバイスは、リージョン内のゲートウェイに対して認証済みWebSocketを開きます。ゲートウェイは必要に応じてオリジンを検証し、フレームサイズと送信レートを制限し、認可をリフレッシュし、ping/pongとリースを用いて切断された接続を検出します。RFC 6455は接続の仕組みを提供しますが、認証、確認応答、シーケンス制御、再試行、バックプレッシャーの制御はアプリケーションプロトコルが担います。

主要なフレーム構成は次のように表現できます:

text
SEND {
  conversation_id, client_message_id, body, client_sent_at
}

ACK {
  client_message_id, message_id, conversation_seq, accepted_at
}

MESSAGE {
  conversation_id, message_id, conversation_seq, sender_id, body, accepted_at
}

SYNC {
  device_sync_cursor, limit
}

client_message_idは一度生成され、その送信デバイスからのすべての再試行で再利用されます。message_idは受信者側の重複排除に使用されるサーバー識別子です。conversation_seqは、単一の会話内における表示およびキャッチアップの順序を示します。accepted_atは診断用のサーバー時刻であり、順序決定の基準ではありません。

ステップ3:ACKを返す前に、論理送信ごとに1回コミットする。

ゲートウェイはSENDをチャットサービスに転送します。サービスは該当する会話シャードを取得し、送信者を認証し、最新のメンバーシップバージョンでメンバーシップを検証し、サイズを検証して、ユーザーおよび会話ごとのレート制限を適用します。シャードオーナーがその会話に対して受理された書き込みを直列化します。

単一の永続トランザクション内で、次のシーケンス番号を割り当て、メッセージを書き込み、(sender_device_id, client_message_id) → message_idのような一意のマッピングを記録します。重複したリクエストに対しては、メッセージを新たに追加するのではなく以前の結果を返します。クォーラムコミットされたレコードのみがACKを受け取ります。ACKが失われた場合でも再試行は安全です。コミット前にストレージ処理が失敗した場合、ACKは送信されません。

メッセージはconversation_idでパーティショニングされ、conversation_seqでソートされます。メンバーシップの変更も順序付けされるか、有効なシーケンス境界を参照するため、認可が結果整合性の最新メンバーキャッシュのみに依存することはありません。フェンシングされたオーナーエポックにより、フェイルオーバー後に古いオーナーが書き込みを受理するのを防ぎます。

ステップ4:永続コミット後にファンアウトを実行する。

コミットされたログから配信タスクが発行されます。接続ディレクトリは(user_id, device_id)をゲートウェイおよび接続リースにマッピングします。ダイレクトメッセージや最大200人のグループの場合、ファンアウトワーカーはメッセージのシーケンス番号時点で有効なメンバーシップスナップショットをロードし、オンラインデバイスをゲートウェイごとにグループ化して、バッチ化されたゲートウェイコマンドを送信します。本文は1回だけ保存され、ファンアウト処理では受信者ごとに永続本文をコピーするのではなく、参照または軽量イベントを伝送します。

ゲートウェイは各接続の制限付き送信キューにイベントを配置します。デバイスはローカルでイベントを受理した後、単調増加する配信カーソルを返します。接続が低速な場合、ゲートウェイは無制限のバッファリングを停止し、再同期対象としてマークして、アプリケーション理由コードとともに切断します。永続ログが真実のデータソースであり続けるため、メモリ上のライブ配信が破棄されてもメッセージが失われることはありません。

オフラインユーザーに対しては、プライバシーに配慮したモバイルプッシュ通知(ヒント情報)を送信できます。プッシュ通知は起動の仕組みであり、メッセージの保存や配信証明ではありません。アプリ起動時、クライアントは認証を行い、永続サービスから同期を実行します。

ステップ5:再接続とマルチデバイス同期を明示的に設計する。

各デバイスは不透明なdevice_sync_cursorを永続化します。GET /sync?after=cursorまたは同等のフレームは、順序付けられた会話の差分、メンバーシップの変更、レシートの差分、および新しいカーソルを返します。サーバーは、レスポンスから除外されたイベントを超えてカーソルを進めてはなりません。カーソルが期限切れの場合や差分が大きすぎる場合、サーバーは単一接続で無制限のリプレイを試みるのではなく、制限付きのスナップショットと継続トークンを返します。

リアルタイム配信と同期処理は重複する可能性があるため、クライアントはmessage_idでマージし、(conversation_id, conversation_seq)でソートします。新しいデバイスはポリシーで許可された履歴を受信し、独自のカーソルを確立します。既読状態はユーザー単位かつ会話ごとに単調増加しますが、配信状態はデバイスごとに保持される場合があります。集約ルールにおいて、「配信済み」が「いずれかのデバイス」を指すのか「すべてのアクティブなデバイス」を指すのかを定義する必要があります。

ステップ6:レシート、プレゼンス、入力中表示を正確に維持する。

既読の更新には、表示された最大のconversation_seqが含まれます。サーバーは条件付き最大値を使用するため、遅れて到着したリクエストによってカーソルが巻き戻ることはありません。Matrix仕様のレシートモデルは、既読が過去の位置を置き換える差分である理由と、単なる受信がユーザーの閲覧の十分な証拠にならない理由を示しています。

プレゼンスと入力中表示は別の経路を通ります。ゲートウェイは短いプレゼンスリースを更新します。タイピングイベントは認可およびレート制限され、単一の会話にスコープされ、合算(コアレス)され、数秒後に期限切れとなります。過負荷時には破棄される場合があり、永続メッセージログに入ることはありません。「最終接続時刻」には、ハートビートトラフィックが書き込みストームに発展するのを防ぐため、明示的なプライバシーポリシーと粗い粒度での更新が必要です。

ステップ7:信頼性を主張する前に障害経路を設計する。

  • ACKの喪失:クライアントは同じclient_message_idで再試行し、サーバーは保存済みの結果を返します。
  • ゲートウェイのクラッシュ:デバイスはジッターを伴って再接続し、カーソルから再開します。接続リースは期限切れとなります。
  • ファンアウトワーカーのクラッシュ:永続配信タスクが再試行され、ゲートウェイとクライアントが重複排除します。
  • 会話オーナーのクラッシュ:新しいエポックとクォーラム状態によって後任が選出され、古いオーナーはフェンシングされます。
  • 低速デバイス:制限付きキューにより、無制限のメモリ消費を防ぎ再同期をトリガーします。
  • ホットな会話:単一のシーケンサーが書き込みレートの上限となります。コミットをバッチ化し、ホットシャードを隔離し、製品のレート制限を適用します。通常のハッシュパーティションを追加しても、単一の厳密なシーケンスを並列化することはできません。
  • メンバーシップの競合:メンバーシップの変更をメッセージとともにシーケンス化し、有効期間に照らして認可します。
  • リージョン障害:古いホームリージョンをフェンシングした後にのみ、昇格したレプリカに会話をルーティングします。目標復旧時間および未ACKメッセージの潜在的損失は、確認済みメッセージの無損失保証とは切り離して扱われます。

再接続の試行には、ジッター付き指数バックオフとアドミッション制御を使用します。これを行わないと、リージョンゲートウェイの再起動時に500万の健全なクライアントが一斉にハンドシェイクストームを引き起こし、復旧が妨げられる可能性があります。

ステップ8:階層化されたテストとオブザーバビリティで不変条件を証明する。

プロパティベーステストにより、再試行、配信順序の逆転、メンバーシップ変更、オーナーエポックをシミュレートし、クライアントIDごとの単一論理メッセージ、一意な会話シーケンス、単調増加カーソル、および削除境界以降の不正メッセージが存在しないことをアサートします。統合テストでは、コミット前、コミット後ACK前、ファンアウト中のプロセスをクラッシュさせます。カオステストにより、ゲートウェイ、ワーカー、シャードオーナー、ゾーン、接続ディレクトリのパーティションを停止させます。

負荷テストでは、500万の長時間接続、ピーク時毎秒230,000件の送信、グループファンアウト、低速受信者、一斉再接続をモデル化します。受付レイテンシ、リアルタイム配信レイテンシ、同期遅延、クライアント重複排除前後の重複率、シーケンスの欠落、ホットシャードの飽和度、送信キューバイト数、再接続アドミッション、認可されていない読み取り拒否を監視します。カナリアリリースは、耐久性と認可の不変条件が維持されている場合にのみ展開を拡大します。

高品質な回答例

「まず、3つの異なる結果を定義します。サーバーによる永続的な受付、デバイスへの配信、ユーザーによる既読です。サービスは、クォーラムがメッセージを保存した後にのみACKを返します。ネットワーク配信は少なくとも1回(at-least-once)のセマンティクスを維持するため、送信側で生成されたクライアントメッセージIDにより再試行を冪等化し、受信側はサーバーメッセージIDによって重複排除を行います。

クライアントはリージョンごとのWebSocketゲートウェイに接続します。接続ディレクトリが各ユーザーデバイスを保持するゲートウェイをファンアウトワーカーに通知しますが、ゲートウェイ自体は履歴を保持しません。チャットサービスは会話IDごとにすべての書き込みをフェンシングされた現在のオーナーにルーティングします。そのオーナーがメンバーシップを再確認し、会話ごとのシーケンス番号を割り当て、メッセージと冪等性結果をアトミックに保存します。無関係な会話は並列に実行されますが、アクセスが集中する会話は意図的に直列化のボトルネックとして扱われます。

コミット後、ワーカーはオンラインデバイスへファンアウトします。失敗した配信やオフライン時の配信は、カーソルベースの同期APIを通じて補完されます。リアルタイム経路とリプレイ経路は重複する可能性があるため、メッセージIDで重複を吸収し、会話シーケンスによってローカルな順序を復元します。既読カーソルは最大シーケンス番号によって進みます。プレゼンスと入力中表示は有効期限付きのベストエフォートな状態を使用し、永続メッセージをブロックすることはありません。

1日20億件のメッセージでは、平均イングレスは毎秒約23,000件となり、10倍のピーク時には毎秒約230,000件を見込みます。プロンプトの前提である1KB換算で、論理メッセージストレージは1日あたり約2TB、3レプリカで約6TBとなります。500万接続に対して、ゲートウェイ1台あたり実測50,000接続の限界と仮定すると、最小で100ノード、ゾーン予備を考慮して稼働率70%で約150ノードが必要になります。

ACK消失、ゲートウェイおよびオーナー障害、古いエポック、重複ファンアウト、低速デバイス、メンバーシップの競合、ホットなグループ、再接続ストームに対する検証を行います。リリース判定基準は、確認済みメッセージの消失ゼロ、重複排除後の論理メッセージ重複ゼロ、シーケンスの逆行ゼロ、メンバーシップ期間外のアクセス不可、および代表的な負荷下でのリアルタイム配信p99目標の達成とします。」

よくある間違い

  • 間違い:サーバー受付、配信、既読を単一のステータスとして扱う → 結果:信頼性と未読メトリクスが検証不能になる → 対策:独立した単調な状態とオーナーを定義する。
  • 間違い:ネットワーク上での「厳密に1回(exactly-once)」配信を約束する → 結果:ACK消失や再接続時に説明不能な重複が発生する → 対策:安定した送信IDと重複排除を備えた「少なくとも1回(at-least-once)」トランスポートを使用する。
  • 間違い:すべてのメッセージをグローバルに順序付ける → 結果:無関係な会話が単一のボトルネックを共有してしまう → 対策:各会話内でのみシーケンスを割り当てる。
  • 間違い:永続コミットの前にACKを返す → 結果:プロセスやゾーンの障害により、受理済みメッセージがサイレントに消失する → 対策:クォーラムコミットされたレコードのみにACKを返す。
  • 間違い:WebSocketゲートウェイに履歴を保存する → 結果:接続の移動がデータ移動を伴うようになり、ゲートウェイ障害が履歴消失のリスクとなる → 対策:ゲートウェイは制限された接続状態のみを保持し、ステートレスに保つ。
  • 間違い:低速デバイス向けに無制限にバッファリングする → 結果:単一のクライアントがゲートウェイのメモリを枯渇させる → 対策:キューを制限し、切断して永続ストレージから再同期させる。
  • 間違い:プレゼンスや入力中表示を永続ログに記録する → 結果:期限切れとなる一時的なトラフィックがコストを押し上げ、メッセージを遅延させる → 対策:認可され、レート制限された、ベストエフォートなTTL経路を使用する。
  • 間違い:最新メンバーの古いキャッシュのみで認可を行う → 結果:削除されたユーザーが競合の隙間に送受信できてしまう → 対策:メンバーシップ境界を順序付け、それに対して受付をフェンシングする。
  • 間違い:アイドル状態のソケット数だけでゲートウェイをサイジングする → 結果:TLS、ハートビート、ファンアウト、再接続によりキャパシティ計画が破綻する → 対策:目標p99で全ワークロードをベンチマークし、障害時のヘッドルームを確保する。

フォローアップの質問と回答

フォローアップ1:エンドツーエンド暗号化をどのように追加しますか?

送信側デバイスでメッセージ本文を暗号化し、暗号文とルーティングに必要なメタデータのみを保存します。各デバイスはIDキー、署名済みデバイスリスト、会話キーの配布を必要とし、デバイスやメンバーの追加・削除時にはポリシーに従ってキーのローテーションまたは再配布を行います。サーバーは依然として暗号文の順序付けやルーティングを行えますが、サーバー側での検索、コンテンツモデレーション、リカバリ、プレビュー生成、不正利用対策は制約を受けます。配信メタデータ、参加者セット、タイミング、サイズは引き続き観測可能であるため、暗号化によってメタデータのプライバシー対応が不要になるわけではありません。

フォローアップ2:トラフィックが集中した1つのホットなグループを複数のシーケンサーに分割できますか?

別の順序決定権限を設けない限り、単一の厳密な連続シーケンスを維持したまま分割することはできません。会話を通常のシャードにハッシュ分割しても、マージや合意形成のポイントが残ります。まずはコミットをバッチ化し、シャードを隔離した上で、会話ごとの制限を適用します。製品側で部分順序が許容される場合は、スレッドや送信者ごとにパーティショニングして因果関係を明示することも可能ですが、コントラクトとクライアントの実装複雑性が変化します。

フォローアップ3:送信者にはACKが表示されていますが、受信者が1週間オフラインのままです。メッセージは配信されましたか?

そのデバイスには「配信」されておらず、「受理」された状態です。永続メッセージは保持ポリシーに従って利用可能なままであり、プッシュ通知によってデバイスを起動できます。再接続時、デバイスは自身のカーソルから同期を行い、その後に配信を報告します。製品UIとメトリクスは、「サーバー受理」「いずれかのデバイスに配信済み」「すべてのアクティブなデバイスに配信済み」「既読」を明確に区別して管理する必要があります。

フォローアップ4:編集や削除は順序付けとどのように連動しますか?

履歴を不可視に変更するのではなく、元のメッセージを参照する新しい順序付きイベントとして表現します。クライアントはイベントストリームを現在のビューに畳み込み(fold)ます。編集や削除が受理された時点で認可がチェックされ、ポリシーによって時間制限や、削除時にコンテンツを完全消去するか、トゥームストーン(削除標識)を付けるか、セカンダリストレージから非同期消去するかが定義されます。

フォローアップ5:削除されたメンバーが古いカーソルを使って再接続した場合はどうなりますか?

同期サービスは、単にカーソルを所持しているかだけでなく、ユーザーのメンバーシップ有効期間を評価します。そのユーザーに認可されたイベントのみを返し、メンバーシップ削除境界を含めます。カーソルは不透明な位置情報であり、アクセス権限(capability)ではありません。サーバーはデバイス上に既に保存されたデータを消去できないため、キャッシュされた添付ファイルやローカルコピーには個別の失効・保持ポリシーの定義が必要です。

フォローアップ6:非常に大規模なパブリックチャンネルをどのようにサポートしますか?

最大200人のグループ向け「書き込み時ファンアウト(fan-out-on-write)」設計は適合しなくなります。チャンネルログを1回保存し、フォロワーにはカーソルを用いたプル型で取得させ、コンパクトな未読通知やプッシュ通知のみをファンアウトし、人気のセグメントをキャッシュして、個別の配信レシート要件を緩和します。パーティショニング、モデレーション、ディスカバリ、著名人チャンネルのホットスポット対策が主要な課題となるため、同じ設計の数値を引き上げるのではなく、別個のワークロードとして扱う必要があります。

公開情報ソース

関連する質問

関連面接ツール

システム設計の回答には「回答する」を使用

まず要件を明確にし、スケール、アーキテクチャ、コンポーネント選定、トレードオフの順に進めます。

ツールを見る