Google Docsにおける同時編集の仕組み
Google Docsでは、多くの人が同時に一つのドキュメントを編集できます。
二人のユーザーが全く同じ瞬間に、全く同じ行を編集した場合、何が起こるのでしょうか?
標準的なシステムは、データの読み取り、修正、保存という手順で動作します。もし二人が同時に保存した場合、二人目のデータが一人目のデータを上書きしてしまいます。その結果、一人目の作業内容は失われてしまいます。
Google Docsは、Operational Transformation (OT) を使用することで、この問題を回避しています。
タイピングのたびにドキュメント全体を送信するのではなく、小さな「操作(operation)」を送信します。
例えば:
- ユーザーAが位置6に「Beautiful」を挿入。
- ユーザーBが位置6に「Amazing」を挿入。
もしサーバーがこれらを変更なしに適用した場合、一方の編集が消えてしまいます。
その代わりに、サーバーはこれらの操作を変換します。
サーバーは、まずユーザーAがドキュメントを更新したことを認識します。これによりドキュメントの長さが増えます。サーバーがユーザーBの操作を処理する際、位置を6から16へと変更します。
最終的なテキストは「Hello Beautiful Amazing World」となります。
両方の編集が保持されます。
このシステムは、以下の技術的柱に基づいています:
- 常時接続のためのWebSockets。
- どの編集がどのバージョンに由来するかを把握するためのバージョン管理。
- 変更をブロードキャストするためのリアルタイム・イベントストリーム。
Google Docsはドキュメントをロックしません。ロックしてしまうと、一人がタイピングしている間、他の全員の作業が止まってしまうからです。
その代わりに、インテリジェントなマージ(統合)を使用しています。
また、システムはカーソルの位置も変換します。誰かがあなたの前方にテキストを追加した場合、現在位置を見失わないようにカーソルが前方に移動します。
Google DocsはOTを使用していますが、Figmaのような多くの新しいツールはConflict-free Replicated Data Types (CRDT) を使用しています。CRDTを使用すると、中央サーバーなしでユーザーが変更をマージできます。
システムデザインを学習しているなら、以下のポイントを覚えておきましょう:
- 低レイテンシのためにWebSocketsを使用する。
- コンフリクト解消のためにOTまたはCRDTを使用する。
- 変更を追跡するためにバージョン番号を使用する。
- ユーザー体験を向上させるためにカーソルを同期させる。
Google Docsはコンフリクトを防ぐのではなく、編集内容を変換することでコンフリクトを解消し、全員が同じ結果を見られるようにしています。
