精选
2021年11月,THORN 开启封闭性内测,共七百多位用户参与。
虽然 THORN 在交互设计和写作体验方面的重视,得到了不少用户的认可,但有不少用户抱怨 THORN 在网络环境不稳定的时候,使用体验并不好。当时,我们的第一反应是,这好像不是 THORN 的问题。
但紧接着,我们心里就冒出个疑问,对于写作类应用来说,网络真的是必须的吗?以此为契机,团队接下来的讨论延伸了一系列的问题,特别是关于隐私和安全方面的问题。
我们果断暂停了开发工作,停下来重新思考 THORN 应该是一个怎样的软件应用?然后,基于隐私、速度和实用的基础,经过大量的调研和实践,我们开始认识到本地优先之于 THORN 的无限可能性:
我们相信数据所有权和实时协作并不矛盾。可以创建具有云应用程序所有优点的软件,同时还允许您保留对您创建的所有数据的所有权和控制权。
我们将这种类型的软件称为本地优先软件,因为它优先使用本地存储,而不是远程数据中心中的服务器。
在云应用程序中,服务器上的数据被视为数据的主要副本;如果客户端拥有数据的副本,则它只是从属于服务器的缓存。任何数据修改都必须发送到服务器。在本地优先应用程序中,我们交换了这些角色:我们将本地设备(笔记本电脑、平板电脑或手机)上的数据副本视为主要副本。服务器仍然存在,但它们保存数据的辅助副本,以帮助从多个设备进行访问。
紧接着,我们豁然开朗,好像所有的问题都被解决了。
回到前面对本地优先软件的描述,好像和一些具备云端备份的本地写作软件没什么区别对吧? 其实不然,请继续往下看。
不抛弃云端,但是本地优先
对于多设备同步和用户协作,传统的基于云的解决方案已经在很多产品和服务上取得了成功。尽管它们允许您在任何地方访问您的数据,但所有数据的访问都必须通过它们的服务器进行,您只被允许做服务器允许您做的事情。因此您的所有数据,包括对这些数据的更改历史,都会被完整地记录下来。
换句话说,您根本没有完全拥有这些数据,数据的所有权和控制权被服务提供商所掌控,您无从反抗,只能认为这些服务提供商会遵循他们提出的用户协议和隐私政策,并妥善处理您的所有数据。
另一方面,您也受制于提供服务的公司。如果服务不可用或者关闭,您将无法再访问使用该软件创建的数据,即使您可以导出数据,但如果没有服务器,大多数情况下,您通常无法正常使用软件。这也是大多数用户信任大公司或者是有雄厚资本背景公司的原因,这些公司更不可能倒闭,所以可以提供较长且更加稳定的服务。
您或许用过一些软件,这些软件通过 iCloud 或者是 WebDAV 网盘在设备之间同步数据,而且数据通常保存在本地磁盘上的文件中,因此您拥有对数据的完全控制权和所有权:您可以做任何您想做的事情,包括长期存档、制作备份以及使用其他程序操作文件。
您不需要任何人的许可即可随时访问您的文件,无需经过某家公司运营的服务器。这些软件通常可以保证您的绝对隐私,而且没有任何审查。但是,它们无法为您带来实时同步、在线协作等功能。
因此,在隐私和协作之间,您需要做出艰难的取舍。难道我们不能两全其美吗?
当然可以,答案就是“本地优先”。本地优先软件有七个特点:
快速响应:数据的主要副本保存在本地设备上,用户永远无需等待网络连接。与其他设备和用户的数据同步在后台静默地进行。
多设备同步:数据保存在每台设备的本地存储中,而且这些数据还能在用户工作的所有设备上自动同步。
网络可选:无论是否在线,用户随时可以读取和写入数据。网络连接可用时,本机设备会自动和其他设备同步。
协作:本机设备和其他设备(无论这些设备是否是您的)支持对同一数据进行实时协作。
长寿:您的数据应该可以无限期地访问。由于您具有本机软件和数据副本,这个软件就可以永远工作。即便软件制造商破产倒闭,您也可以继续运行该软件的最后发布版本。而且您可以将数据全部导出为通用格式,使用其他软件进行访问。
安全和隐私:和传统基于云的解决方案不通,本地优先软件不存在一个保存了用户所有数据的集中式数据库,您的本地设备只存储您自己的数据,通过避免使用集中式云数据库保存每个人的数据,本地优先软件具有很好的安全性和隐私性。
数据所有权和控制权:这里的数据所有权和控制权并不是法律意义上的,而是指本地优先软件制造商不会限制您访问本机副本数据,你被允许在任何时候通过任何方式复制和修改这些数据,而无需通过服务提供商的 API 去访问数据。
看到这里,大家对本地优先软件应该有足够的理解了。但是令人遗憾的是,以上描述的是只是一种理想状态。
那么具体应该如何实现尽可能的实现本地优先软件呢?
本地优先软件的基础设施:CRDT
根据 Ink&Switch 的相关研究,CRDT 是最可能用于本地优先软件实现的一种基础技术。
CRDT 就是一种特殊的数据结构,它能让多个设备可以协作编辑同一个数据对象。具体来说,如果设备 A 和设备 B 现在同时编辑一个数据对象 data,随着时间的推移,分别产生两个更改序列 changes-on-A 和 changes-on-B, 只要这设备 A 和设备 B 分别把自己的更改一个一个地发送给对方,那么两设备就可以在本地计算出 data 的最终状态。
听起来好像没什么特别的对吧?但是神奇之处在于,CRDT 在数学上被证明可以确保只要收到了对方对 data 所有的更改(无须关心更改的到达顺序),两设备各自计算出的 data 的最终状态肯定是一致的。
我们可以设想,并不存在一个中央服务器去处理和解决所有用户的数据冲突,而是每个设备自行解决冲突,而 CRDT 可以确保在每个设备自行计算的情况下,所有设备还能计算出完全一致的结果。
上述描述其实并不准确,但是已经可以表达 CRDT 可以带来的核心优势,**去中心化**。
去中心化的前提是在客户端应用和实施 CRDT,因为现有的协作软件,也完全可以使用在其服务端软件中应用 CRDT 技术去解决数据冲突。比较有代表性的是 Azure Cosmos DB、Redis、Riak、Weave Mesh、SoundCloud 的 Roshi 和 Facebook 的 OpenR。
如果你还有兴趣继续探索 CRDT,可以看 Alexei Baboulevitch 的这篇文章 Data Laced with History 和 Martin Kleppmann 的这个视频CRDTs and the Quest for Distributed Consistency。
看到这里,我想您已经明白,CRDT 之于本地优先软件的意义。
我们相信 CRDT 有潜力成为新一代软件的基础。正如分组交换是互联网和网络的支持技术,或者电容式触摸屏是智能手机的支持技术一样,我们认为 CRDT 可能是协作软件的基础,让用户完全拥有他们的数据。
THORN 的数据同步引擎
让我们回到具体实现,大家可以注意到,对于 CRDT 来说,仍然需要一个服务端,以确保客户端连入网络时,可以随时从服务端获知其他客户端对数据的更改(当然,客户端也需要将自己离线时对数据的更改告知服务端)。

上图是 THORN的数据同步机制的逻辑结构示意图,你可以注意到:
每个用户的所有客户端设备,都拥有一份保存在本地数据库中的数据副本;
而 THORN 同步服务也有一份数据副本,但是保存在阿里云 OSS 中。
严格来说,THORN 官方同步服务是一个更可靠的“客户端”,因为它会将加密后的数据副本保存到开启了同城冗余和异地容灾的阿里云OSS中,相对于用户设备上的本机存储介质,可以提供高达12个9的数据持久性。
同时,当您主动删除某个数据对象时,官方同步服务会向所有的在线设备广播删除事件,但是如果存在离线设备(由于网络原因并没有收到广播的删除事件),那么被删除的数据就会在这个离线设备中留存(您后续可以随时通过这个离线设备,重新同步(恢复)将这个数据对象)。
另一方面,任一客户端设备连接到 THORN 同步服务时,客户端和 THORN 同步服务会相互传送数据更新,以完成数据同步,然后 THORN 同步服务会将其他客户端对数据的更新推送给该客户端,同时该客户端的数据更改,也会随时传输给同步服务。
因此,同步服务和客户端设备之间是一种星型架构:

如图,客户端1、3、4,和 THORN 同步服务之间的同步,保证了他们各自的数据副本状态一致。
当客户端3重新连入网络时,也能通过和 THORN 同步服务的数据同步,达到全部所有数据副本状态的最终一致。
好像也没什么特别的?传统的基于云的解决方案,不也是类似星型架构吗。这样理解是不对的,传统模式是一种集中式的星型架构,客户端受制于服务端,没有服务端,客户端几乎无法正常运行。
而 THORN 的模式是一种类似 P2P 网络的星型架构,客户端和服务端是平等关系,而且没有同步服务,客户端也能独立正常运行(但是没有用户协作和多设备同步)。
客户端和服务端的平等体现在,服务端可被替代,您可以使用 THORN 官方运维的同步服务,也可以使用自部署的 THORN 同步服务。值得一提的是,同步服务之间可以快速地完成切换,您所需要做的就是在更换同步服务,重新同步一次全量数据即可。
看到这里,我相信您心里肯定冒出个大问题,前述的本地优先软件隐私和安全,THORN 的这种模式好像并不能保证?
如何保证隐私和安全?
隐私和安全问题,其实只涉及到THORN 同步服务本身,因为在前述的理解下,它不属于您的资产和设施,即使它的存在是出于为您提供更好的服务(多设备同步和协作),是善意地辅助您,而不是恶意地窥探您。
难道您不担心,某个邪恶的 THORN 团队成员,去偷看您的数据吗?虽然您在本地拥有您的数据,但是同步服务也有您的数据。
或许您并不关心您的数据被黑客窥探,但是在现实中,由于法律法规的限制和保密义务,有很多人根本无法使用云应用程序。
那么,THORN 是如何做的呢?
THORN 中,每个用户可以创建多个空间,每个空间可以使用不同 THORN 同步服务。
理解上面这一点,非常重要。因为我们未来会基于不同的技术实现不同的 THORN 同步服务。不同的同步服务实现,在隐私和安全方面的保障程度,可能完全不同。
现在的方案
现在的 THORN 同步服务基于 Websocket 实现,不仅对计算和网络资源需求低,而且具备很高的性能。
官方运维的 THORN 同步服务使用了开启了同城冗余和异地容灾的阿里云OSS作为存储介质,但是我们后续也将支持连接用户自己购买的对象存储服务。此外, THORN 同步服务也将支持自部署。
指的一提的是,由于 THORN 同步服务没有传统的数据库依赖,即便是个人用户自部署 THORN 同步服务,所需的资源和成本也是极低的。
当然,这一切都是可选的,取决于您如何选择:
信任 THORN 团队:使用 THORN 官方同步服务,保存一份数据副本到 THORN 官方的对象存储服务
最大限度的保障数据所有权和控制权:使用 THORN 官方同步服务,保存数据到自己购买的对象存储服务上;
最大限度的保证隐私和数据主权:使用自部署官方同步服务,保存数据到自己购买的对象存储服务上。
对于 1 这种情况,您的数据在传播时,在相关法律法规的要求下,您的数据可能会面临审查,具体细节可查看《THORN 服务协议》中有关「内容相关的规则」的部分。
但是无论1,2或者3,您都应该遵从《THORN 服务协议》,合法地使用 THORN,如果违反您所在地区的法律法规和《THORN 服务协议》,您将会被禁止使用 THORN 同步服务。
未来的方案
鉴于 THORN 足够简洁和优秀的扩展性和兼容性,我们期望在未来通过更加成熟的 Web 3.0 相关技术(例如 web3.storage),从底层技术上解决数据安全和隐私问题。
综上所述,我们为您带来了崭新的 THORN 2022。
本篇文章成文,我们参考了 Ink&Switch 的 Local-first software, 以及 Alexei Baboulevitch 的这篇文章 Data Laced with History 和 Martin Kleppmann 的这个视频 CRDTs and the Quest for Distributed Consistency。