13

常见分布式应用系统设计图解(九):协同编辑系统

 3 years ago
source link: https://www.raychase.net/6429
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这里讲的 “协同编辑”,指的是 “Collaborative Editing”,多个人同时一起编辑同一个文件,比如说 Google Docs,国内的有有道云协作、石墨文档之类的。这样的系统倒不如我们前面提到的那些应用系统那么 “火”,但是,依然具备相当的典型性。

第一印象,这样的一个系统,我们可以简单做出如下归类:

  • 这是一个文件编辑系统,这是最最基础的一个功能性需求,它就好像是 Windows 下的记事本,只不过它是在线的。
  • 这是一个分布式系统,客户端/浏览器可以在不同的地方,通过网络和服务端联结,用户的编辑行为转化为请求发送给服务端。
  • 这是一个异步系统,编辑编辑过程中,事件都是由不同用户的浏览器/客户端上对文件的来触发的。

因此,根据上面的三条,我们可以 “没什么新意” 地归纳出一些相应的需求和限制,不过,这个系统里面还隐含了这么几个特殊的要求:

  • 自动保存:所见即所得,所见即所存。因此文件的变更需要自动同步到服务端保存,并且显然一般情况下,这是一个增量同步。这个增量同步是双向的,既有客户端到服务器,也有服务器到客户端。
  • 冲突处理:在多数情况下,系统要能够自动处理合并多人对于同一个文件在同一时间的修改,这个文件多数是文本文件,或者至少是内容结构化了的文件。
  • 版本管理:要能够追溯修改历史,回退版本,甚至单独剔除或合并特定用户的修改等等。
  • 权限管理:不同的人可以具备不同的权限,比如有的人只可以读,有的人可以写。
zYzyIri.png!mobile
  • 图中虚线表示控制流,也包括协同编辑文件的创建,但是实际的文件内容数据流动,是通过实线完成的。
  • 上半部分表示的是一个文件创建的过程,Application Server 接受请求,通过 Metadata Service 把文件创建出来。文件赋予不同的权限组,Auth Service 管理权限记录。
  • 下半部分,用户把编辑内容增量写入 Channel Service,这样的事件经过鉴权和简单处理后放入待处理队列。Collaboration Service 从队列中取出事件并处理,它在完成编辑操作以后,把 merge 完的变更事件写到另一个队列中去,并通过 Channel Service 把更新推送给另一个用户。
  • 一般的系统,在服务端推送的时候建立长连接的比较多,但是这类系统在客户端推送和服务端推送两头都要建立长连接。 客户端每发生一次变更,就要把事件通知到 Channel Service,反之亦然 。之所以这样做,有两个原因,
    • 一是因为数据要尽可能实时地同步;
    • 二是这样的数据包一般都比较小,长连接可以减少开销。
  • 所谓增量变更,常见的包括三种:insert、delete 和 retain,前两个用于对当前光标位置的字符增删操作,后者用于移动光标。
  • 对于文件修改的冲突自动解决和合并,有一个这类系统使用的特定的技术,叫做 Operational Transformation (OT)。基本上就是把根据用户编辑文档的版本和字符所在位置,以及编辑行为(增加或/和删除),转换并合并编辑到实际文档中位置的一种技术。
  • 对于修改历史记录的存储,肯定要存放一个基础版本加上每个变更。每个变更都很小,且按照时间序列排好,这样的变更数据使用支持索引的 KV 数据库或者列数据库都可以实现。
    • 但是,如果只使用这个机制,在变更非常多的情况下,读出所有数据才能得到最新版本,效率很低,其中一个改进的办法是一定变更数量以后进行 archive,或者说对一系列变更做一个 snapshot。
    • 因此,整体看来,这就是一个 Snapshot + WAL(Write Ahead Log)的典型实现。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK