实时协作应用程序如何保存数据?

问题描述

我以前已经借助套接字完成了一些非常基本的实时应用程序,并且出于好奇而一直在阅读有关它的更多信息。我读到的一篇非常有趣的文章是关于Operational Transformation的,我学到了一些新东西。阅读后,我一直在想如果要保留这些数据,则何时或如何将它们真正保存到数据库中。对于可能发生的情况,我有两个假设/理论,但是我不确定它们是否正确和/或解决此问题的最佳解决方案。它们如下:

在此示例中,假定它是实时协作白板:

  1. 对于每一次进行的编辑(例如画一条线),套接字都会向合作的每个人发送一条消息。但同时,我会将数据存储在数据库中。 解决方案出现的问题是我需要访问数据库的时间。对于用户绘制的每一行,我都需要访问数据库进行存储。
  2. 使用轮询。对于这个理论,我认为将每个数据保存在服务器的临时存储中,然后在“ x”时间之后,它将从临时存储中获取所有数据并将其保存在数据库中。 该理论的问题是临时存储中可能发生故障(例如,电气故障)。如果临时存储在将数据保存到数据库之前丢失了数据,那么我将永远无法恢复它们。

类似的实时协作应用程序(如Google Doc,Slides等)如何将数据存储在其数据库中?他们是遵循我提到的一种理论还是存储数据的方式完全不同?

解决方法

他们完全依靠更改日志+最新文档版本+定期快照(如果允许他们有时间浏览文档历史记录)。

  • 这类似于大多数数据库的事务系统的工作方式。确认更改合法之后,数据库将更改以非常快速的数据结构写入磁盘aka。只会附加更改值的日志。该日志通过专用数据结构在内存中复制,以加快读取速度。

  • 读入时,数据库将检查内存中的数据结构,并将更改与缓存或磁盘中存储的内容合并。

  • 定期将内存和日志中存在的更改与磁盘上的数据结构合并。

总结一下,在您的情况下:

  • 当服务器进行操作转换时,会发生两件事:
  1. 它按原样存储在数据库中,以避免任何损失(等同于日志)
  2. 它会更新内存中的数据结构,以便在用户请求最新版本(相当于内存数据结构)的情况下快速重放更改
  • 当用户请求最新文档时,服务器将检查内存中的数据结构,并针对由于以下几点而可能滞后的最后存储的合并文档重播更改

  • 定期将日志应用于“最后存储的合并文档”,以减少为生成最新文档而必须重放的OT量。

无论如何,获得明确答案的最佳方法是查看可满足您需求的开源代码,例如etherpad。