如何在客户端服务器体系结构中为已删除的数据生成增量?

时间:2013-08-03 16:13:50

标签: architecture language-agnostic synchronization client-server

我和我的同事创建了一些客户端服务器体系结构程序,这些程序使用增量来将客户端与服务器同步。与删除记录有关的问题似乎出现在多个项目中。 服务器如何在本地删除记录,但仍有足够的信息为未来的客户生成删除增量信息?

示例1:

实时游戏使用UDP客户端 - 服务器在游戏之间同步实体。仅发送包含修改的游戏状态和先前丢弃的分组数据的增量。如果服务器删除实体,它可以发送删除增量,告诉每个客户端删除该对象。除非丢弃数据包,否则此方法有效。这对于正常状态数据是可以的,因为服务器可以识别丢弃了哪些数据并从中重新传输增量,但这意味着服务器无法在本地删除服务器实体(没有从每个客户端进行完全确认),因为没有将存在数据以生成删除增量。

示例2:

客户端希望与存储在服务器上的数据库同步。服务器为服务器上的每条记录存储修改日期。当客户端请求同步时,它会传输更新的最后日期。服务器收集自该日期以来已修改的所有记录,并将它们发送到客户端。仅当服务器保持每条记录都被删除并使用标志表示删除时,才能使用删除操作。服务器无法安全删除本地存储的记录。

在这两个示例中,我能想到的唯一解决方案是保留包含所有已删除内容的某种记录,或者在某个日期/时间之后强制执行完整同步。这些似乎不是可持续或优雅的模型。 解决此类问题有哪些可持续的方法?

1 个答案:

答案 0 :(得分:1)

为什么这似乎不可持续?许多同步框架使用它,它被称为Tombstoning,afaik。该记录被删除或标记为已删除,而在另一个表中(如果涉及数据库)则保留对已删除项目的引用。这样,系统就能够同步已删除的记录。实际上,它不仅仅是删除数据。有些人可能会说记录的每次更新都是删除。因为永远不会再找到旧版本的记录。因此,如果保持“旧”数据很重要,则不要向数据存储区发送更新,而只发送插入内容。

如果UDP和数据包丢失,您必须围绕它设计软件。如果游戏为某些已经删除的实体提交数据,则忽略它或正确回应它。这里有很多选择。

您可能也在关注事件采购。它不是圣洁的或任何东西,但它与常规CRUD的工作方式不同。相反,它使用CQRS来分离命令和查询侧,并使用事件源来创建事件流。您只存储事件。因此,每当您想要声明某个实体时,您都会回读所有事件。它可能总是以插入,零或多个更新开始,然后是一些删除语句。你将拥有你需要知道的一切。这些事件也会发送给创建最新状态的读取模型的其他组件。这样,一些UI可以从读取模型中读取并且速度极快,但每个状态更改都通过事件流来处理,为每个事件处理业务逻辑。

如果您对此感兴趣,请阅读Greg Young和其他许多人的CQRS和事件采购。