4

最近,我开始调查 Couchbase Server 作为该项目的候选者。我现在正在研究的一个特定场景是如何使 Couchbase 充当“事实来源”,这就是我深入研究耐用性方面的原因。

所以这里是ACID Properties 和 Couchbase的一个片段:

如果持久性要求失败,那么 Couchbase 可能仍会保存文档并最终将其分发到集群中。我们所知道的是,就 SDK 所知,它并没有成功。您可以选择根据此信息采取行动,将更多 ACID 属性引入您的应用程序。

那么接下来想象一下。我插入/更新一个文档,主节点失败,直到数据进入任何副本。假设primary已经消失了很长时间。现在,我现在不知道数据是否已写入磁盘......所以这里一个可怕的部分是“Couchbase 可能仍会保存文档并最终将其分布在整个集群中”。这意味着,据客户所知,数据没有成功,因此用户会看到一个错误,但是如果主节点重新上线,它可能会突然出现在系统中。

我是否正确阅读了此声明?如果我是,用 Couchbase 处理它的最佳做法是什么?

4

3 回答 3

4

这个问题的更新:

Couchbase 6.5 引入了对事务的支持:

transactions.run((txnctx) -> {
    // get the account documents for Andy and Beth  
    TransactionJsonDocument andy = txnctx.getOrError(collection, "Andy");
    JsonObject andyContent = andy.contentAsObject();
    int andyBalance = andyContent.getInt("account_balance");
    TransactionJsonDocument beth = txnctx.getOrError(collection, "Beth"); 
    JsonObject bethContent = beth.contentAsObject();
    int bethBalance = bethContent.getInt("account_balance");

    // if Beth has sufficient funds, make the transfer
    if (bethBalance > transferAmount) {
            andyContent.put("account_balance", andyBalance + transferAmount);
            txnctx.replace(andy, andyContent);
            bethContent.put("account_balance", bethBalance - transferAmount);
            txnctx.replace(beth, bethContent);
    }
    else throw new InsufficientFunds();  
    // Commit transaction - if omitted will be automatically committed 
    txnctx.commit();
});

持久性也得到了改进,现在您可以在 3 个级别之间进行选择:majority、persistToActive、persistToMajority

阅读更多 :

于 2019-08-19T17:11:12.610 回答
3

简短的回答:

打开自动故障转移,你会没事的。

更长的答案:

听起来您在这里担心一个非常狭窄的边缘案例。以下是我的理解:

  1. 您使用 SDK 保存文档,并为其提供 persists_to 持久性要求。
  2. Couchbase 确认文档已保存到内存中。
  3. SDK 开始检查以确保它被持久化到磁盘和/或被复制。
  4. 在极其短暂的时间窗口内,节点会关闭。该文档已保存到磁盘,但没有复制到另一个节点,并且主节点没有故障转移
  5. SDK 操作会返回一个错误,说它不满足持久性要求。(我可能错了,它可能会返回一个不同的错误,这意味着你可以采取不同的行动)。
  6. 您通知用户某事失败。
  7. 节点重新启动,重新加入集群,文档就在那里。
  8. 困惑的用户?

如果这是正确的,关键是第 4 步。首先,这似乎是一个非常罕见的边缘情况。所有这三件事都必须是真实的才能担心这种情况。我的 Couchbase 内部知识不是坚如磐石,所以这种情况可能是不可能的(但我会继续前进)。

如果您在良好的网络和良好的机器上运行 Couchbase,那么网络分裂/节点下降不应该经常发生。因此,您可以打开自动故障转移。请记住,我们的文档没有写入磁盘。因此,当发生故障转移时,该文档仅在 RAM 中,因此它永远消失了(既然您告诉用户,没有混淆)。

再说一次,我不是 Couchbase 内部的专家,所以据我所知,这一切都是如此,但听起来你需要做的就是打开自动故障转移,你会没事的。默认关闭;这个想法是您应该首先了解它是什么并选择加入。但对于大多数系统,使用自动故障转移。

于 2018-10-05T13:10:39.477 回答
1

因此,这是我与 Couchbase 家伙交谈时发现的:

情景#1

一种情况可能是,在它被确认为持久化之后,但在它被复制之前,节点失败了。在这种情况下,如果您不对节点进行故障转移,当它重新联机时,该项目将被复制。

情景#2

另一种情况是,您可以启用自动故障转移,并且在主服务器接收到它之后但在它被复制或持久化之前,自动故障转移启动并将副本带到主服务器。在这种情况下,您的应用程序将无法达到所要求的持久性要求。如果前一个主节点确实重新上线,在它重新加入集群之前,它将与当前集群的状态重新同步,这意味着该项目处于活动状态的位置现在是当前状态。

所以我问过“当前一个主节点重新联机并使用本地持久但未复制的项目并开始重新同步时,这些项目会被擦除还是什么? ” -

是的,这真的是故意的。您可以将那些以前保留的项目视为没有发挥作用的“替代历史”。当失败发生时,集群选择了一个新的起点,让每个人都同意,从那里开始宇宙向前发展。当旧节点恢复并尝试加入这个宇宙时,它必须在对那个宇宙有共同理解的情况下这样做,这可能意味着丢弃未传递的数据。

当然,在实践中,由于复制是内存到内存的,而且磁盘 IO 往往会有更高的延迟(一个项目的复制和项目的持久性都是同时调度的),所以事情往往会被复制而不是持久化,但是没有保证。此外,该应用程序(通过 SDK)也具有一些影响结果的能力,以及我们所讨论的耐久性要求功能。

完整的对话在这里

于 2018-10-16T20:10:16.283 回答