代表的な面接トピック

システムデザイン面接:リアルタイム共同編集エディタの設計

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

質問

日間アクティブユーザー数2,000万人、ピーク時のオンライン接続数200万、アクティブに編集中のユーザー数20万人を抱えるリアルタイム共同リッチテキストエディタを設計してください。アクティブなエディタは平均して毎秒2回の更新を生成し、1つのドキュメントに100人の同時編集者が存在する場合があります。リモートの編集はp95で200ミリ秒以内にオンラインの共同編集者に届く必要があり、ユーザーは最大24時間のオフライン編集が可能で、確認応答(ack)済みの編集は失われてはなりません。競合解決、API、データモデル、同期と永続化、プレゼンス、マルチリージョン動作、権限、セキュリティ、キャパシティ、検証について説明してください。

問題と適用シナリオ

段落、見出し、リスト、太字テキスト、コメントアンカーをサポートするリアルタイム共同編集エディタを設計します。システムは 2,000万人の日間アクティブユーザーを抱え、ピーク時には200万接続を維持し、20万人のユーザーがアクティブに入力を行っています。アクティブな エディタは平均して毎秒2回の更新を生成し、アクセスの集中する1つのドキュメントには100人の同時編集者が存在する場合があります。オンラインの共同編集者は リモートの編集をp95で200ミリ秒以内に確認できる必要があります。ユーザーはオフラインで最大24時間編集し、再接続後にマージできます。 サーバーによって確認応答された編集が失われてはなりません。カーソル、選択範囲、オンラインステータスは一時的に失われてもかまいません。

システムは、閲覧者、コメント投稿者、編集者の権限、権限の変更、バージョン履歴、ユーザーごとの取り消し(Undo)、 マルチリージョンアクセスもサポートします。面接では、CRDTやOTアルゴリズムをゼロから証明したり、特定の企業の プライベートアーキテクチャを再現したりすることは求められません。候補者は競合解決モデルを選択し、それをエディタのデータ構造、 トランスポート、永続化、認可境界に結びつけ、その設計が保証できないことを明記する必要があります。

2026年時点の英語および中国語の面接資料では、共同編集はOT対CRDT、WebSocket接続、ドキュメントルーム、カーソルプレゼンス、 オフライン編集、永続更新、スナップショットリカバリにまたがるシステムデザイン問題として提示されています。Yjsのドキュメントは、 可換・結合・冪等な更新、ステートベクトルによる差分同期、非永続的なAwarenessに関する主要なエビデンスを提供します。この組み合わせにより、 プロンプトは代表的で技術的に検証可能なものとなっています。

面接官が評価しているポイント

第1に、候補者が「WebSocketを使用する」だけで終わらず、並行処理の収束を解決しているか。WebSocketは双方向チャネルを 提供するにすぎません。2人のユーザーが同じ位置に挿入した場合の結果を決定するものではありません。優れた回答は、 サーバー仲介のOTモデルとCRDTモデルを比較し、提示された制約に対して1つを選択します。

第2に、回答がローカルの体験とサーバーの永続性保証を分離しているか。タイピングはネットワークのラウンドトリップの前に ローカルに適用される必要があります。「確認応答済みは失われない」を実現するには、サーバーがackを返す前に、アベイラビリティゾーンをまたいで 更新を永続的にレプリケートする必要があります。それまで、クライアントは更新を保留キューに保持し、同一の操作IDで再試行します。

第3に、設計が永続的なコンテンツと一時的なプレゼンスを分離しているか。ドキュメントの内容、コメントアンカー、バージョン履歴は 復旧可能である必要があります。カーソルの移動は高頻度で変動し、切断後に期限切れになります。すべてのカーソル移動をドキュメントログに 永続化すると、コストが増加し、古い状態でリカバリが汚染されます。

第4に、候補者がリッチテキストのセマンティクスについて論理的に考えられるか。収束する文字シーケンスが自動的に有効な ドキュメントツリーになるわけではありません。リスト、テーブル、コメントアンカー、スキーマのアップグレード、Undoスコープには、 明示的なモデル、バージョン、不変条件が必要です。単純な整数オフセットも、リモートユーザーがその前方に挿入した瞬間にずれてしまいます。

最後に、キャパシティ、ホットスポット、マルチリージョンの所有権、権限、検証が一貫したループを形成しているか。優れた回答は、 書き込み負荷とルームごとのファンアウトを計算し、低速クライアントを制限し、権限が取り消されたオフライン編集を単純にマージできない理由を説明し、 順序変更された更新、重複、パーティション、フェイルオーバーを使用して収束と永続性を証明します。

回答前の明確化のための質問

  • 何が編集されていますか? プライマリ設計では構造化されたリッチテキストツリーを使用します。画像バイトはオブジェクトストレージに配置され、ドキュメントには参照と属性が含まれます。
  • 製品における競合の意味は何ですか? 並行する更新は、互いに上書きすることなく決定論的に収束します。システムは、矛盾する2つの文のビジネス意図までは推測しません。
  • 確認応答(acknowledged)とは何を意味しますか? サーバーは、更新がホームリージョン内の3つのアベイラビリティゾーンにレプリケートされた永続ログに入った後にのみackを返します。
  • グローバルな線形順序は必要ですか? いいえ。コンテンツはCRDTを通じて収束します。ログオフセットは監査、リカバリ、確認応答のウォーターマークのために存在し、マージの正確性のためではありません。
  • クライアントはどのくらいの期間オフラインのままでいられますか? 最大24時間です。ローカルのCRDT状態と未確認の更新を保持し、差分を交換する前に再認可を行います。
  • 権限レベルは何ですか? viewerは読み取り、commenterはコメントドメインのみを変更し、editorはコンテンツを変更します。参加、再接続、およびすべての書き込みが認可されます。
  • カーソルの状態は永続的ですか? いいえ。プレゼンスはハートビートとTTLを使用します。失われたカーソル更新は、次の状態更新によって置き換えられます。
  • 複数のリージョンが同じドキュメントへの書き込みを受け入れることはできますか? プライマリ設計では、各ドキュメントにホームリージョンを割り当てて書き込みをそこに転送し、認可、監査、フェイルオーバーを簡素化します。
  • バージョン履歴はどのくらいの期間保持されますか? ユーザーに表示されるバージョンは30日間保持されると想定します。これらは、オンライン同期に使用される圧縮されたスナップショットとは異なります。
  • エンドツーエンドの暗号化は対象範囲内ですか? メイン設計では、サーバーが権限とコンテンツスキーマを検証できるようにします。エンドツーエンドの暗号化は追加のトレードオフです。

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

「サーバー中継型のCRDTを採用します。編集をローカルに適用し、各WebSocket更新を再認可し、ゾーン間の永続化が成功した後にのみackを返し、ドキュメントルームごとにブロードキャストします。再接続時は不足している差分にステートベクトルを使用するか、スナップショットを読み込みます。永続コンテンツとTTLベースのプレゼンスは分離します。ピーク負荷は40万回の更新、つまり約120 MB/sです。100人の編集者がいるホットルームでは毎秒約19,800回のリモート配信が発生するため、ゲートウェイが更新をバッチ処理し、低速クライアントのバッファを制限します。順序変更や重複した更新、24時間のオフライン再接続、権限の取り消し、ホームリージョンのフェイルオーバーをテストして、収束と永続性を確認します。」

ステップバイステップの詳細解説

7つの不変条件から始めます。

  1. ローカル入力は決してネットワークを待たず、すべての更新を受信したレプリカは同じ有効なドキュメントに収束する。
  2. サーバーは、ゾーン間の永続化が成功した後にのみコンテンツの更新を確認応答する。
  3. 再試行、重複ブロードキャスト、順序変更された配信によって、編集が2回適用されたり最終結果が変わったりしてはならない。
  4. 現在のIDと権限はサーバーセッションから取得され、更新ペイロード内のロールから取得されることは決してない。
  5. コンテンツ、コメント、バージョン履歴は復旧可能であり、カーソルとオンラインステータスは期限切れになってもよい。
  6. スキーマに互換性のないクライアントは、未知の構造を書き込み続けることはできない。
  7. すべてのドロップ、拒否、機能低下、リカバリ結果は可観測である。

ステップ1:OTとCRDTの選択

OTは通常、順序付けられたサーバーバージョンをコンテキストとして使用し、受信した各操作を並行操作に対して変換します。変換エンジンが確立された サーバー主導のシステムに適していますが、変換関数、保持履歴、オフラインのリベースがすべて正確である必要があります。CRDTはデータ構造内に 並行性をエンコードします。更新は異なる順序で複数回到達する可能性があり、すべての更新を受信した後にレプリカが収束します。コストとしては、 因果関係メタデータ、削除マーカー、複雑なリッチテキストバインディング、認可やセマンティックな競合の個別処理が挙げられます。

プロンプトでは24時間のオフライン編集とマルチリージョンアクセスが求められているため、プライマリ設計では、サーバーリレーと永続ストレージを備えた 実績のあるシーケンス/ツリーCRDTを選択します。CRDTは分散デプロイを必要とせず、サーバーを排除するわけでもありません。サーバーは引き続き、 ID、スキーマ検証、サイズ制限、永続的な確認応答、履歴、コンプライアンス、ルームファンアウトを担います。

ステップ2:構造化ドキュメントとメッセージ規約の定義

ドキュメントのルートには、安定したIDを持つブロックが含まれます。段落、見出し、リストアイテムはCRDTテキストと書式設定属性を保持します。 コメントスレッドは別ドメインに存在し、相対位置を持つ範囲にアンカーされます。スキーマバージョンは、許可されるノード、属性、 移行ルールを定義します。整数オフセットは不安定です。その前方に挿入があると、指している対象が変わってしまいます。相対位置はCRDT要素に アタッチされ、レプリカが収束した後に一貫して解決されます。

WebSocketサブプロトコルは、以下のアプリケーションメッセージを使用できます。

text
join {
  documentId, sessionId, schemaVersion, stateVector
}

update {
  documentId, clientId, clientSeq, schemaVersion, payload
}

ack {
  clientId, clientSeq, durableOffset
}

sync {
  payload, durableOffset, schemaVersion
}

presence {
  sessionId, relativeCursor, relativeSelection, statusSeq
}

(documentId, clientId, clientSeq)は再試行の冪等性キーです。durableOffsetは確認応答と監査をサポートしますが、 CRDTのマージの正確性には関与しません。メッセージには圧縮および非圧縮のサイズ制限とスキーマの許可リストがあります。 未知のノードや不正なドメイン変更は、ブロードキャストされずに明示的に拒否されます。

ステップ3:読み込み、ライブルーム、ストレージパスの分離

text
Client
  -> HTTPS snapshot service -> metadata + snapshot store
  -> WebSocket gateway -> document room router -> collaboration service
                                              -> durable update log
                                              -> room pub/sub -> gateways

Client
  -> presence channel -> regional ephemeral store -> room fan-out

クライアントはまずHTTPS経由でドキュメントのメタデータ、現在のスキーマ、最近の圧縮スナップショットを読み込み、次に WebSocketを開きます。ゲートウェイは接続とルームのサブスクリプションを管理しますが、マージルールを作成することはありません。コラボレーション サービスはドキュメントごとにそのホームリージョンにルーティングし、各更新を認可・検証し、永続化し、ackを返し、公開します。ルーム バスは購読者がいる各ゲートウェイに一度だけ公開し、各ゲートウェイは受信者ごとにノード間メッセージを送信するのではなくローカルでファンアウトします。

ステップ4:ローカル編集、確認応答、再試行を明示的なステートマシンにする

ローカルの編集は即座にビューを更新し、ローカルに永続化された保留キューに入ります。オンライン中、クライアントはメッセージ数を減らすために、 20〜50ミリ秒のウィンドウで隣接するキーストロークをバッチ処理する場合があります。このタイミングは入力時の仮定であり、インタラクションテストによって 調整する必要があります。更新ごとに、サーバーはセッションを認証し、現在の権限を読み取り、スキーマとリソース制限を検証し、 レプリケートされたログに追加し、ackを返し、ブロードキャストします。ackを受信して初めて、更新が保留キューから削除されます。

コミット後、ackの前に接続が切断された場合、クライアントは同じclientSeqで再試行します。サーバーの一意性制約により、 元の確認応答を返すことができます。CRDTの冪等性により適用の重複も安全ですが、監査および請求レコードには依然として重複排除が必要です。 低速クライアントには制限付きの送信バッファが割り当てられます。高水位標(High-water mark)を超えると、ゲートウェイはまずプレゼンスをドロップし、 1つの接続が無制限にルームのメモリを消費することを防ぐために、クライアントにステートベクトルからの再同期を要求します。

ステップ5:オンライン、オフライン、再接続の同期にステートベクトルを使用する

可換、結合、冪等なCRDT更新により、レプリカは異なる順序で更新を受信し、安全に再試行できます。再接続時、クライアントは すでに保持している因果関係の状態を記述したステートベクトルを送信し、サーバーは不足している差分を計算します。差分が大きすぎる場合、 スキーマが変更された場合、またはオンライン履歴ウィンドウが期限切れになった場合、サーバーは現在の完全なCRDTスナップショットを送信し、 その後、引き続き認可されているローカル更新を適用します。

順序は、認証、認可、スキーマ交渉、そしてコンテンツの交換です。ユーザーがオフライン中に編集権限が取り消された場合、 収束したとしても変更を受け入れる権限にはなりません。サーバーは安定したpermission_revokedエラーを返し、エクスポートまたはコピー用の ローカルリカバリパスを保持しますが、ドラフトを共有ドキュメントに書き込むことはありません。システムは、現在のアクセス制御を維持するために 「すべてのオフライン編集をマージする」ことを諦めます。

ステップ6:スナップショット、バージョン履歴、コンパクションの設計

永続ログはdocumentIdによってパーティション分割され、更新ID、作成者、スキーマ、ペイロード、受信時間、永続オフセットを記録します。 バックグラウンドのコンパクターはCRDT状態をロードし、増分を直接ロード可能なスナップショットに結合し、カバーされた オフセットを記録します。新しいスナップショットが検証に合格し、オブジェクトストレージで永続化され、リカバリおよび監査ウィンドウのための ロールバックポイントが保持された後にのみ、古い増分を削除します。

バイナリ更新のマージは重複情報を削除しますが、それ自体が削除されたコンテンツをガベージコレクションするわけではありません。削除マーカー、 オフライン同期、コメントアンカー、ユーザーごとのUndo、履歴バージョンが相互に影響し合います。したがって、コンパクションには実際の ドキュメントを使用したテストが必要です。ユーザーに表示される履歴は独立した名前付きスナップショットまたは変更インデックスを保存します。オンライン同期のコンパクションは 製品のバージョン履歴の代替にはなりません。

ステップ7:プレゼンスの分離とホットスポットのファンアウトの制御

プレゼンスには、セッション、表示名、色、相対カーソル、選択範囲、単調増加するstatusSeqが含まれ、ハートビートと TTLによって更新されます。ドキュメントのCRDTや永続ログに入ることは決してありません。受信者は古いシーケンス番号を破棄し、切断状態は 期限切れになります。1つのカーソル更新が失われても、次の更新がそれを置き換えるため、一時的な影響しかありません。

100人の編集者がいるルームで毎秒2回の更新が発生すると、毎秒200回のコンテンツ更新が生成されます。各更新を他の99人のユーザーに送信すると、 プレゼンスを除いても毎秒約19,800回のリモート配信になります。ゲートウェイは短いタイムスライスの更新をバッチ処理し、ドキュメントルームごとに公開し、 プレゼンスの頻度を制限し、接続ごとにバイトとメッセージのウォーターマークを強制します。非常にアクセスの集中するドキュメントには専用の ルームアクターとPub/Subパーティションが割り当てられる場合がありますが、システムが負荷を軽減するために永続コンテンツの編集をサンプリングすることは決してありません。

ステップ8:グローバルキャパシティと接続リソースの再計算

20万人の編集者が毎秒2回の更新を行うと、毎秒40万回の更新が発生します。平均300バイトのバイナリペイロードの場合、 生の書き込みは約120 MB/s、つまり10.37 TB/日になります。レプリケーション、インデックス、ヘッダー、スナップショット、バージョン履歴は別枠です。 ゲートウェイ接続が50 KiBを占有する場合、200万接続には約100 GiBのゲートウェイ状態が必要です。ゲートウェイあたり20,000接続とすると、 障害やデプロイのマージンを考慮する前のベースラインは100台のゲートウェイです。

これらの見積もりは出発点です。生のコンテンツストレージよりも前に、ホットルームのアウトバウンドトラフィック、TLSとエンコーディングのCPU、低速クライアントのバッファ、永続ログのパーティションが ボトルネックになる可能性があります。ドキュメントおよびテナントごとの更新レートとファンアウトレート、ackレイテンシ、ステートベクトルの 差分サイズ、再接続、バッファウォーターマーク、スナップショットの経過時間、収束チェックの失敗を監視します。

ステップ9:マルチリージョン動作、フェイルオーバー、セキュリティの制約

ドキュメントのメタデータには、ホームリージョンと増加するエポックが記録されます。クライアントは近くのゲートウェイ経由で接続し、コンテンツの書き込みは ホームリージョンにルーティングされます。即時のローカル適用により、リージョン間のRTTがタイピングに影響するのを防ぎます。ホームリージョンで障害が発生した場合、コントロール プレーンがまずエポックを進め、新しいリージョンがレプリケートされたログと最新のスナップショットから復元します。永続化レイヤーは 古いアクターのエポックを拒否するため、2つのルームオーナーが同時に永続的な確認応答を発行することはできません。

CRDTの収束は、認可の決定、永続的な確認応答、またはフェイルオーバーのフェンシングを代替するものではありません。セキュリティには、 ドキュメント、更新、レート、展開率の制限、Origin、セッション、ドキュメントの認可チェック、転送中および保存時の暗号化、 共有、権限変更、エクスポートの監査、アクセストークン、ドキュメント本文、正確なカーソル詳細を除外したログも必要です。

ステップ10:プロパティテストと障害注入による設計の証明

同じ初期ドキュメントに対して複数のクライアントから更新を生成します。それらをランダムな順序で、重複、遅延、バッチ処理を 交えて適用します。すべてのレプリカは、同じシリアライズ結果と有効なスキーマで終了する必要があります。同位置への挿入、重複する 削除、子の編集中における親の削除、並行する書式設定とテキスト、コメントアンカー、ユーザーごとのUndo、スキーマのアップグレードを追加します。

永続追加後、ackの前にコラボレーションサービスを強制終了します。再試行により、監査済みの更新が1つ生成される必要があります。ack後、 ブロードキャストの前に強制終了します。リカバリによって更新が配信される必要があります。24時間のオフライン後に再接続し、ステートベクトルの差分パスと スナップショットパスの両方を実行します。オフライン更新を送信する前に権限を取り消します。共有の永続化レイヤーはローカルのリカバリを保持しつつ、 それらを拒否する必要があります。最後に、コンテンツとプレゼンスを含む100人の編集者のホットルームで負荷テストを行い、p95レイテンシ、メモリウォーターマーク、 および意図した機能低下順序を検証します。

高品質な回答例

「3つの規約から始めます。ローカル入力は即座に適用されること、すべての更新を受信したレプリカは収束すること、3つのアベイラビリティゾーンにわたってログが永続化された更新のみが確認応答されることです。24時間のオフライン要件には実績のある構造化CRDTが適していますが、サーバーは認証、スキーマ、永続化、ファンアウトに関して信頼できる単一の情報源であり続けます。

CRDTスナップショットを読み込んだ後、クライアントはドキュメントルームに参加します。ローカルの編集が最初に適用され、clientId + clientSeqの下で保留キューに入り、バイナリ更新としてWebSocket経由で送信されます。コラボレーションサービスは現在の権限、スキーマ、リソース制限を再チェックし、更新を永続的に追加し、ackを返し、ルームに公開します。再試行でも同じシーケンスが維持されます。更新は順序変更と重複を許容します。再接続時、クライアントはステートベクトルを送信し、不足している変更または完全なスナップショットを受信します。オフライン中に権限が取り消された場合、共有書き込みは拒否され、ローカルエクスポートのみが利用可能なままになります。

コンテンツとプレゼンスは別々のパスを使用します。カーソルは相対位置を使用し、TTLベースのプレゼンスは永続ログに記録されません。各ドキュメントにはホームリージョンとエポックがあります。フェイルオーバーでは、レプリケートされたログとスナップショットから復元する前にエポックを進めるため、古いルームオーナーが更新の確認応答を継続することはできません。

ピーク時には、20万人の編集者 × 毎秒2回の更新 = 毎秒40万回の更新になります。300バイトの場合、これは生の更新で120 MB/s、10.37 TB/日になります。100人の編集者がいるホットドキュメントでは毎秒約200回の更新と19,800回のリモート配信が発生するため、ルームバスは1回公開し、ゲートウェイがローカルでバッチ処理およびファンアウトを行い、低速クライアントのバッファを制限します。すべてのレプリカが収束するまで更新を並べ替えて重複させることでシステムを証明し、その後、ack境界周辺のクラッシュ、24時間のオフライン再接続、権限の取り消し、スキーマのアップグレード、ホームリージョンの障害を注入して検証します。」

よくある間違い

  • 「WebSocketを使用する」とだけ言う → トランスポートは並行編集を解決しない → OTまたはCRDTを選択し、収束とコストを説明する。
  • 編集ごとにドキュメント全体を保存する → 同時実行ユーザー同士が上書きし合い、帯域幅がドキュメントサイズに応じて増大する → マージ可能な増分更新を送信する。
  • インメモリ受信後にackを返す → プロセスのクラッシュにより確認応答済みの作業が失われる → ゾーンをまたいだ永続追加の後にackを返す。
  • CRDTを認可として扱う → 数学的な収束は、取り消されたユーザーを阻止できない → 参加、再接続、およびすべての書き込みを認可する。
  • カーソルを整数オフセットとして保存する → 並行挿入によって意図した位置がずれる → CRDT要素に対する相対位置を使用する。
  • カーソル移動をコンテンツログに永続化する → 高頻度で変動するエフェメラルな状態がストレージとリカバリを肥大化させる → TTLプレゼンスチャネルを使用する。
  • 厳密に1回(Exactly-once)の配信を主張する → 再接続やブロードキャストによって重複が発生する可能性がある → 冪等な更新、一意のID、再生可能な状態を使用する。
  • スナップショット直後にすべての履歴を削除する → オフライン同期、ロールバック、Undo、スキーマ移行に必要なコンテキストが失われる可能性がある → 検証済みのリカバリウォーターマークを超えたもののみを回収する。
  • コンテンツの流入(Ingress)のみを計算する → ホットルームのファンアウトと低速クライアントが最初にリソースを使い果たすことが多い → 配信、流出(Egress)、バッファも計算する。
  • コントロールプレーンなしでどこでもアクティブな書き込みを受け入れる → 認可、ack、フェイルオーバーの所有権が曖昧になる → ホームリージョンとエポックを使用する。

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

フォローアップ1:なぜOTではなくCRDTを選択するのですか?

24時間のオフライン要件と、順序変更・重複が発生するマルチリージョントランスポートはCRDTの更新モデルと整合しており、実績のある実装ではステートベクトルを使用して差分を交換できます。OTも依然として有効です。実績のあるサーパートランスフォームエンジン、単一の順序付けられた編集サービス、限定されたオフライン動作を備えている場合、より制御されたメタデータとサーバーセマンティクスを提供できます。決定は製品の制約とチームの能力に基づいて行われるべきであり、単に一方の頭字語が普遍的に新しいと主張することによるものではありません。

フォローアップ2:CRDTを使用すれば、永続的な更新ログは不要になりますか?

いいえ。CRDTはマージと収束を解決します。確認応答された永続性、監査、履歴、リカバリ、新しいデバイスの読み込みには、依然として永続的な状態が必要です。システムは増分をスナップショットに圧縮し、リカバリウィンドウの後に古いログエントリを回収できますが、検証可能な永続性の境界とロールバックポイントを保持する必要があります。

フォローアップ3:オフラインユーザーの権限が取り消された場合はどうなりますか?

コンテンツを交換する前に、再認証と認可を行います。安定したエラーで共有書き込みを拒否し、エクスポートまたはコピー用のローカルコピーを保持します。黙って破棄してはなりません。業務上、管理者が隔離された承認領域でドラフトを確認できるようにする場合もありますが、そのパスが現在のドキュメントACLをバイパスすることはできません。

フォローアップ4:複数ユーザーがいる場合、Undoはどのように機能しますか?

デフォルトでは、現在のユーザーの最新のローカル操作を取り消し、CRDTを通じて逆操作をマージします。古いスナップショット全体を復元すると、他のユーザーのその後の作業が消去されてしまいます。操作ごとにユーザーとトランザクションの境界を記録し、対象のUndoウィンドウの間は削除されたコンテンツを保持し、構造変更についてはエディタバインディングで可逆的なセマンティクスを定義します。

フォローアップ5:並行編集後にカーソルが飛ばないようにするにはどうすればよいですか?

絶対的な文字オフセットではなく、CRDT要素に対する相対位置としてカーソルとコメントアンカーを保存します。リモートの更新を適用した後、相対位置を現在のインデックスに解決します。アンカーと親構造の両方が削除された場合は、明示的な製品ルールに従って、カーソルを非表示にするか、コメントをデタッチ済みとしてマークするか、最も近い有効なブロックにフォールバックします。

フォローアップ6:1万人が1つのドキュメントを開いた場合はどうなりますか?

編集者と読み取り専用の閲覧者を分離します。各コンテンツの更新をルームバスに1回公開し、ゲートウェイからファンアウトします。読み取り専用クライアントは、エディタの正確性を変えることなく、より低い頻度でマージされた更新を受信するか、有効期間の短いスナップショットをポーリングできます。プレゼンスには表示されている参加者またはサンプリングされた参加者のみを表示し、すべての接続に制限付きの送信バッファを設定します。1万人すべてのカーソルを表示するには、専用の帯域幅とUIのバジェットが必要になります。

フォローアップ7:エディタはエンドツーエンドの暗号化をサポートできますか?

サーバーが暗号文を中継および保存する間、クライアントがCRDTの更新を暗号化できます。トレードオフとして、サーバーはリッチテキストスキーマの検証、コンテンツの検索、モデレーション、きめ細かなエクスポート、紛失したデータの簡単なリカバリができなくなります。キーのローテーション、メンバーの削除、古いメンバーのオフライン更新の処理も難しくなります。まず脅威モデルとドキュメント、デバイス、メンバーシップキーのプロトコルを定義する必要があります。WebSocketを単にTLSで保護するだけではトランスポートの暗号化にすぎず、エンドツーエンドの暗号化ではありません。

フォローアップ8:サイレントなレプリカのフォークをどのように検出しますか?

アイドル期間の後または再接続時に、クライアントはそのステートベクトルと非機密の状態ダイジェストを報告します。同じ永続ウォーターマークにあるレプリカのみを比較します。不一致が発生した場合は完全な再同期がトリガーされ、診断サンプルが保持されます。継続的なカナリードキュメントが複数のリージョンから既知の並行更新を発行し、最終的なダイジェスト、スキーマ、ack数、ログウォーターマークを検証します。インフライト中の異なるウォーターマークでダイジェストを比較すると、誤検知が発生します。

公開情報ソース

関連する質問

関連面接ツール

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

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

ツールを見る