同步、协作与 Local First

写在最前

当说到 local first 或者同步(CS 同步,客户端-服务器同步)时,又或是协作时,虽然这三个概念比较相似,但其实存在不小的差别,甚至,因为它们的差别比较微妙,很多地方都被误用了。

在开发应用时,真正重要的其实就是「同步」与「协作」,这两个才是真正的技术手段,而 local first 更多的是一种标签,很多技术都可以标榜 local first,但是却有着不小的差别。

先抛开所谓的 local first 不谈,单纯说下实际场景中的「同步」与「协作」。

同步

同步,顾名思义,一个或多个客户端之间完成数据的同步。

大多数情况下,同步都是存在中心同步服务器的同步,往往都是客户端节点推送修改到服务器、也是由服务器推送修改到其他的客户端节点,在这种情况下,中心同步服务器负责解决数据持久化、客户端节点的管理、数据冲突等问题。

而现在又逐渐存在了去中心化的同步(这里的去中心化和区块链的去中心化不太一样,不要混为一谈),也就是不存在中心同步服务器,客户端节点之间自己交换数据完成同步,在这种情况下,各个客户端节点自己完成全量的数据存储和数据冲突的解决。在去中心的情况下,节点之间的发现其实也存在着问题,因此即使是去中心化的同步,往往也存在着一个中心的信令服务器用于做节点的发现。

另外相比于简单的中心化同步,去中心化的同步在「全量的数据存储」和「数据冲突解决」上也都有着各自的挑战。

在去中心化的同步上,我特意强调了「全量的数据存储」。 在中心化同步的情况下,客户端其实是可以不存储全量数据的,即各种「混合同步」的手段,只在客户端存储最近使用过的数据,而历史数据在使用时再去服务器拉取;这种混合同步的手段被除了微信以外的 IM 工具广泛使用。但是在去中心化的情况下,所有客户端都必须存储全量的数据(甚至全量的历史数据,参见下文数据冲突的解决),这导致去中心化同步时存储所占用的存储空间往往要比中心化同步时占用的存储空间多。

在去中心化的同步上,「数据冲突解决」也有着它的挑战。在出现冲突时,如果使用了中心服务器同步,冲突是由中心服务器解决并通知所有客户端节点的。但是在去中心化的同步时,每个客户端节点独立自行解决冲突,同时需要注意最终应该实现所有节点的数据一致。特别需要注意的是,对于中心同步服务器而言,解决冲突可以用简单的 last-writer-wins(后来的胜利),但是对于去中心的同步而言,次序是无法保证的。

协作

很多情况下, 协作都会与同步混为一谈,但实际上它们主要关注的点还是不同的。一个很重要的点就是实时性:对于同步而言,其他节点的信息在本地可见有着秒级甚至分钟级别的延迟都是可以接受的;但是对于实时协作的情况,需要的是近乎无延迟的信息可见。

TODO

同步 + 协作

现代应用很多都同时提供了同步+协作的手段。

基于 CRDT 做中心同步?

常用技术栈

同步

协作(CRDT)

CRDT Benchmarks

关联阅读

https://www.figma.com/blog/how-figmas-multiplayer-technology-works/