从前,有一位名叫 Maria 的数据分析师。
她多次通过电子邮件发送草稿给不同的人来准备月度报告。
所以她浪费了大量时间并感到沮丧。

直到有一天,她决定使用 Google Docs。
Google Docs 允许通过互联网协作编辑。这意味着许多用户可以实时处理同一文档。
但要正确实现 Google Docs 很困难,有 3 个原因:
- 对同一文档的并发更改应该收敛到同一版本
- 对同一文档的并发更改必须避免冲突
- 任何更改应该对每个用户实时可见
此外,用户应该能够在离线时进行更改。
处理并发的方法
方法 1:使用锁
处理并发的简单方法是使用悲观并发控制。
悲观锁定是使用锁处理并发的机制。它提供强一致性,但不支持实时协作编辑。因为它需要中央协调器来处理数据更改,一次只有 1 个用户可以编辑。简单地说,一次只有一个文档副本可用于写操作,而其他文档副本是只读的。
此外,它不支持离线更改。

地球各地的网络请求
此外,网络往返地球需要 200 毫秒。
这可能导致糟糕的用户体验。所以他们做延迟隐藏。想法是为每个用户在本地保留一个文档副本,然后在本地运行操作以实现高响应性。从而创造比现实更低延迟的错觉。
系统将更改传播给所有用户以保持一致性。

方法 2:最后写入获胜
延迟隐藏的一个简单方法是使用最后写入获胜机制。
但它通过应用最新更新来解决冲突而无需等待协调。所以当高延迟网络中有并发更改时,存在数据丢失风险。
当并发性低时,它可能是一个好的选择。但它不适合这个用例。
继续前进。

方法 3:差分同步
延迟隐藏的另一种方法是通过差分同步。
它为每个用户保留一个文档副本并在本地跟踪更改。当某些内容更改时,系统不发送整个文档,只发送差异(diff)。
但为每个更改发送 diff 存在性能开销。此外,差分同步只跟踪 diff,不跟踪更改背后的原因。所以冲突解决可能很困难。
虽然手动解决冲突会影响用户体验。

方法 4:操作转换(Google Docs 使用)
所以 Google Docs 使用一种称为操作转换(OT)的乐观并发控制技术。
OT 是一种算法,用于在高延迟网络上显示文档更改而无需等待时间。它允许不同的文档副本同时接受写操作。此外,它自动处理冲突解决而无需锁或用户干预。
此外,OT 容忍文档副本之间的分歧并稍后收敛它们。
把操作转换想象成事件传递机制;它确保每个用户拥有相同的文档状态,即使有未同步的更改。
使用 OT,系统将每个更改保存为事件。简单地说,更改不影响文档的底层字符;相反,它将事件添加到修订日志。系统然后通过从头重放修订日志来显示文档。
操作转换将文档保存为一组操作,但正确实现很复杂。
Google Docs 架构
Google Docs 使用客户端 - 服务器架构以简化。
以下是它的工作原理:
1. 客户端
- 维护本地文档副本
- 立即应用用户操作
- 将操作发送到服务器
- 从服务器接收远程操作
- 转换并应用远程操作
2. 服务器
- 接收来自所有客户端的操作
- 为每个操作分配序列号
- 广播操作给所有客户端
- 持久化操作到数据库
3. 操作转换
- 转换并发操作以避免冲突
- 确保所有客户端收敛到相同状态
- 处理插入、删除、格式化等操作
本文为学习目的的个人翻译,译文仅供参考。
原文链接:How Does Google Docs Work。
版权归原作者或原刊登方所有。本文为非官方译本;如有不妥,请联系删除。