我正在解决一个在服务器和多个客户端之间实现数据同步的问题。我了解到事件溯源(Event Sourcing)的概念,并希望使用它来完成同步部分。
我知道这不是一个技术问题,更多是一个概念性的问题。
我本来想将所有事件即时发送到服务器,但客户端被设计成有时离线使用。
服务器存储每个客户端应该知道的所有事件,它不会重放这些事件以提供数据,因为主要目的是在客户端之间同步事件,使其能够在本地重新播放所有事件。
客户端有自己的JSON存储,也保存所有事件并从存储/同步的事件中重建所有不同的集合。
由于客户端可以脱机修改数据,因此具有一致的同步周期并不那么重要。考虑到这一点,当合并不同的事件并在发生冲突时要求特定用户时,服务器应处理冲突。
因此,我遇到的主要问题是确定客户端和服务器之间的差异,以避免将所有事件发送到服务器。我还在处理同步流程的顺序:先推送更改还是先拉取更改?
我目前构建的是服务器端的默认MongoDB实现,在所有查询中隔离特定用户组的所有文档(当前仅处理身份验证和服务器端数据库工作)。在客户端,我构建了一个NeDB存储器(wrapper),使我能够拦截所有查询操作来创建和管理每个查询的事件,同时保持默认查询行为不变。我还通过实现由客户端生成并成为文档数据一部分的自定义ID来补偿neDB和MongoDB的不同ID系统,以便重新创建数据库不会弄乱ID(在同步时,这些ID应在所有客户端中保持一致)。
事件格式将类似于:
{
type: 'create/update/remove',
collection: 'CollectionIdentifier',
target: ?ID, //The global custom ID of the document updated
data: {}, //The inserted/updated data
timestamp: '',
creator: //Some way to identify the author of the change
}
为了在客户端上节省一些内存,我会在某些事件数量时创建快照,这样完全重放所有事件将更加高效。因此,为了缩小问题的范围:我能够在客户端上重放事件,我也能够在客户端和服务器端上创建和维护事件,合并服务器端的事件也不是问题,现有工具复制整个数据库也不是一个选项,因为我只同步数据库的某些部分(甚至不是整个集合,因为文档被分配到不同的组中进行同步)。但我遇到的问题是:
- 确定从客户端发送哪些事件进行同步(避免发送重复的事件,或者全部事件) - 确定要发送回客户端哪些事件(避免发送重复的事件,或者全部事件) - 同步事件的正确顺序(推送/拉取更改)
另一个问题是,将更新直接存储在类似修订版本的文档中是否更有效?
如果我的问题不清楚,有重复(我找到了一些问题,但它们没有帮助我解决我的情况),或者缺少什么,请留下评论,我会尽力保持简单,因为我刚刚写下了可以帮助您理解概念的所有内容。谢谢!