9

我听到的关于 Couchbase 和其他 NoSQL 数据库的最常见问题是如何为记录生成唯一键——或者更具体地说——如何复制常见关系数据库的 AUTO INCREMENT 特性。

Couchbase中经常提到的解决方案是increment函数,你可以在数字键上调用increment,它会依次生成一个新的唯一数字。

我对此的问题是,在复制方面,我无法理解我预见到的巨大问题。

假设您有一个由三个 Couchbase 节点组成的集群,并且您正在存储一个请求日志。您想要键入此日志,以便创建一个名为“requestlog_counter”的条目。

现在假设我们有 4 个 Web 节点,每个节点每秒接收 20 个请求,每个请求都需要记录为“request::{ID})”。那是每秒 80 个请求。

假设节点 1 和 3 有一点点网络延迟,但它们都同时收到这 40 个请求中的一个。您的脚本增加请求计数器(假设此示例当前为 1500)并获取 ID。当然,现在两个 Couchbase 实例都可以将 1501 返回到 Web 节点 1 和 3,并且两个服务器现在都将尝试将它们正在处理的请求存储为“request:1501”。

现在,复制将解决这个问题,基本上最新的将获胜。但是您现在丢失了一个请求的记录。

那么现在这是否意味着实际上您需要一种更好的方法来键入重要数据,并且在 NoSQL 集群环境中应该避免使用自动增量来生成绝对值和唯一键生成?

或者 - 作为密钥生成过程的一部分,您可以做些什么来确保 100% 可靠。

还请考虑使用跨数据中心复制的多集群环境。

谢谢。

麦克风

4

1 回答 1

8

首先根据沙发库文档功能increment,并且decremant在集群内是“原子的”。因此,如果您使用它们来生成“自动增量”,那么一切都应该可以正常工作。

但是,如果您想确保在沙发库中保存新项目时不会覆盖现有的(例如“两个 Couchbase 实例都可能返回 1501”的情况),您可以将存储操作与StoreMode.Add. 因此,如果您同时调用couchbase.store(StoreMode.Add, "request:1501",value),一个请求将成功完成,另一个请求将失败,您可以捕获此“失败”并尝试再次重复该存储操作(为新键获取新的自动递增 id)

于 2013-09-07T18:03:41.963 回答