5

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

示例 1:

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

示例 2:

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

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

4

1 回答 1

1

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

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

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

如果您对此感兴趣,请阅读 Greg Young 和许多其他人的 CQRS 和 Event Sourcing。

于 2013-08-04T07:25:28.737 回答