【发布时间】:2017-03-01 01:32:06
【问题描述】:
我在服务器和多个客户端之间实现数据同步时遇到了问题。 我阅读了有关事件溯源的信息,我想用它来完成同步部分。
我知道这不是技术问题,更多的是概念。
我只是将所有事件实时发送到服务器,但客户端被设计为不时离线使用。
服务器存储每个客户端应该知道的所有事件,它不会重播这些事件来提供数据,因为主要目的是在客户端之间同步事件,使它们能够重播所有本地事件。
客户端拥有一个 JSON 存储,同时保存所有事件并从存储/同步的事件中重建所有不同的集合。
由于客户端可以离线修改数据,因此具有一致的同步周期并不重要。考虑到这一点,服务器应在合并不同事件时处理冲突,并在发生冲突时询问特定用户。
所以,对我来说主要问题是确定客户端和服务器之间的差异以避免将所有事件发送到服务器。我也对同步过程的顺序有问题:先推送更改,先拉取更改?
我目前构建的是服务器端的默认 MongoDB 实现,它在我的所有查询中隔离特定用户组的所有文档(目前仅处理身份验证和服务器端数据库工作)。 在客户端上,我围绕 NeDB 存储构建了一个包装器,使我能够拦截所有查询操作以创建和管理每个查询的事件,同时保持默认查询行为不变。我还通过实现由客户端生成并且是文档数据的一部分的自定义 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
}
为了节省客户端的一些内存,我会在一定数量的事件上创建快照,这样完全重播所有事件会更有效率。
所以,缩小问题范围:我能够在客户端重放事件,我还能够在客户端和服务器端创建和维护事件,合并事件在服务器端也应该不是问题,使用现有工具复制整个数据库也不是一个选项,因为我只同步数据库的某些部分(甚至不是整个集合,因为文档被分配了它们应该同步的不同组) .
但我遇到的问题是:
- 同步时确定从客户端发送什么事件的过程(避免发送重复事件,甚至所有事件)
- 确定要发送回客户端的什么事件(避免发送重复事件,甚至是所有事件)
- 同步事件的正确顺序(推/拉更改)
我想问的另一个问题是,以类似修订的方式将更新直接存储在文档上是否更有效?
如果我的问题不清楚、重复(我发现了一些问题,但它们在我的场景中对我没有帮助)或缺少什么,请发表评论,我会尽我所能保持它很简单,因为我刚刚写下了所有可以帮助您理解这个概念的内容。
提前致谢!
【问题讨论】:
标签: javascript node.js mongodb synchronization event-sourcing