0

在 CouchDB 1.x 中,文档有一个“隐藏”._local_seq字段,用于跟踪数据库在编写文档修订时的状态下的更新顺序。这可以通过{local_seq:true}在设计文档中包含选项来由视图使用,或者由客户端使用?local_seq=true文档 GET 请求上的查询选项来获取。

该字段在 CouchDB 2.x 中仍然可用,但不清楚它的行为方式。由于集群,数据库更新序列现在是“一个不透明的令牌”,而 local_seq 仍然是一个普通整数,在实践中似乎并不总是匹配。

是否有任何关系,特别是如果我将自己限制在单节点集群中?

4

1 回答 1

0

这是我到目前为止所知道的:

对于初学者来说,local_seq在 CouchDB 2.x 下, 的目的确实不太清楚。正如问题中已经提到的,在 database/_changes 级别,序列号已被替换为正式与 local_seq 没有​​任何关系的“不透明令牌”。

更糟糕的是,local_seq与每个文档一起存储的值(或至少可从该文档派生)似乎不是数据库本地的,而是分的!(每个数据库在内部被分成多个部分;您可以在文档中阅读更多关于分片和副本的详细信息。)

因此,尽管在 CouchDB 1.x 中,例如,可以通过发出 local_seq 作为 map-reduce 索引键的一部分来制作自定义更改提要 - 它会与?since=N集群中数据库的 _changes 提要的值匹配 -专注于 CouchDB 2.x 这样的视图会倾向于发出多个文档 [每个分片最多一个],它们具有相同的._local_seq字段!

而从另一个角度来看,在 CouchDB 2.x 下,即使是"seq"与数据库级 _changes 提要中的特定文档相关联的内容也可以随着请求的变化而变化——前缀和/或它之后的大混乱。我不确定是否有办法或任何有用的优势,视图引擎可以map像处理本地序列一样为函数提供“非本地序列”值。


也就是说,从 CouchDB 2.3.0 开始,我发现了一种“巧合”的方式来保留一些有用性:

  1. 通过创建具有1 个副本和仅 1 个分片的数据库,PUT /newdb?n=1&q=1local_seq 值最终在数据库中是唯一的。
  2. seq在这种情况下,数据库级 _changes 提要中每个标记的第一部分似乎与每个更改文档的 local_seq 匹配。即,如果您拆分字符串标记'-'并将第一部分转换为数字,您似乎得到了local_seq。

我会谨慎地依赖这一点,因为:

  • 如果您确实需要扩大规模,并选择使用多节点集群功能来扩大规模,那么任何依赖于上述内容的代码都会中断
  • 它绝不是官方认可的,理论上可以突破一个点释放。CouchDB 开发人员非常清楚 _changes 级别的标记是不透明的,您应该这样对待它们。

所以警告黑客和所有这些,上面的“巧合”确实符合这些令牌目前如何工作的描述:

前面的数字是第二部分中编码的各个更新序列的总和,仅用于欺骗较旧版本的 couchdb 复制器进行检查点。

✅ 如果只有一个更新序列,总和应该是原始序列。

对于给定的分片 [_changes 提要]完全有序的(分片与具有整数序列的 2.0 之前的数据库相同),couchdb 不会打乱该输出 […]

✅ 只有一个分片 [nb 分片而不仅仅是一个节点/副本],您几乎只剩下 2.0 之前的数据库行为。

于 2019-01-23T22:09:28.580 回答