是否可以在基于复制的分布式数据库中删除?



到目前为止,我一直生活在无法真正删除基于复制的分布式数据库中的行的印象中。这一切都在基于复制的中运行良好。但在复制中,您将它们标记为"考虑此删除",并在每个最后一个查询中过滤掉它们。但是您实际上不会从数据库中删除某些内容。我认为现在是验证这一假设是否属实的时候了。

我的理解是,如果发生密钥冲突,您将遇到复制的争用条件。它是这样的:

数据库 A: 在键 11 下添加一个条目 (11A)

数据库 B: 在键 11 (11B) 下添加一个条目

数据库 A: 删除键 11 下的条目

现在取决于这 3 个操作在野外"相遇"的顺序: 预期顺序为:

  • 11A 创建
  • 11 删除(即 11A)
  • 11B 创建

但是,如果发生这种情况呢?

  • 11A 创建
  • 11B 创建(失败,已经是密钥 11)
  • 11 删除

或者更糟糕的是,这个?

  • 11B 创建
  • 11A 创建(失败,已经是密钥 11)
  • 11 删除(将达到 11B)

我假设我们谈论的是一个无领导的分布式数据库,即所有节点都扮演相同的角色(没有主节点),因此读取和写入都可以由所有节点提供服务。否则,如果只有一个主节点,它可以对所有写入/删除施加特定的排序,从而解决您所描述的并发问题。

但是在复制中,您将它们标记为"考虑此删除"并过滤 它们在每次最后一次查询中都出来了。

没错,这样做有两个主要原因:

  • 正确性:如果删除了项目而不是逻辑删除,则可能存在一个不明确的实例,其中咨询了 2 个节点,其中节点 A 具有项目,而节点 B 没有。并且整个系统无法区分该项目是否被删除(但在 A 中删除失败)或该项目是否是最近创建的(但创建在 B 中失败)。对于墓碑,这种区别可以清楚地表明。
  • 性能:这些系统中的大多数不执行就地更新(如RDBMS数据库通常执行的那样),而是执行仅追加操作。这样做是为了提高性能,因为磁盘中的随机存取操作比顺序操作慢得多。因此,通过逻辑删除执行删除与此方法非常吻合。

但是您实际上不会从数据库中删除某些内容。

这不一定是真的。通常,逻辑删除最终会从数据库中删除(以垃圾收集方式)。最终,这里意味着当系统可以确定上述示例不会再针对这些项目发生时,它们将被删除(因为删除已传播到所有节点)。

我的理解是,如果发生密钥冲突,您将遇到复制的竞争条件

这适用于大多数此类分布式系统。结果将取决于操作到达数据库的顺序。但是,其中一些数据库提供了替代机制,例如条件写入/删除。这样,您只能删除项目的特定版本,或者仅当项目的版本是特定版本时才更新项目(因此,如果其他人同时更新了更新,则会中止更新)。Cassandra 的此类操作的一个例子是条件删除和所谓的轻量级事务。


以下是一些描述 Riak 和 Cassandra 如何执行删除的参考资料,其中也包含大量有关墓碑的信息:

  • Riak:对象删除
  • 关于卡桑德拉中的删除和逻辑删除

最新更新