乐观并发控制说明

Optimistic concurrency control clarification

我是 ES7 的新手,正在尝试理解 optimistic concurrency control

我想我明白,当我获取请求文档并在稍后的写入请求中将其 _seq_no_primary_term 值发送到同一文档时,如果值不同,写入将被完全忽略。

但是在我不发送 _seq_no_primary_term 值的默认情况下文档会发生什么情况?即使它具有较旧的 _seq_no_primary_term 值(因此使索引不一致),写入是否会通过,或者只有在值较新时才被处理?

如果是前者,文档最终会一致吗?

我想弄清楚我是否需​​要发送这些值以获得最终一致性,或者我是否可以免费获得它而不发送这些值。

这是一个很棒的分布式系统问题。为了便于阅读,让我将问题分解为子部分,甚至在解释什么是 _seq_no_primary_term 之前,因为 ES 站点上对这些的解释不多。

  1. _seq_no 是每次操作(更新、删除、索引)分配给 ES 文档的增量计数器,例如:- 第一次索引文档时,它的值为 1,接下来update 会有 2 个,下一个 delete 操作会有 3 个,依此类推。读取操作不会更新它。
  2. _primary_term 也是一个增量计数器,但仅当副本分片由于网络或任何其他故障而被提升为主分片时才会更改,因此如果集群中的一切都很好,它就不会更改, 但如果出现某些故障并且其他副本提升为主副本,则它会增加。

来到第一个问题,

问:- 在我不发送 _seq_no 和 _primary_term 值的默认情况下,文档会发生什么情况?

回答:- 您可能遇到了丢失更新的问题,假设您有一个正在更新的计数器,同时有 2 个请求将计数器值读取为 1 并尝试递增 1。现在当您没有在上面指定这些时条款明确,然后由ES计算。 现在两个请求同时到达 ES,然后 ES(主分片)将通过增加序列号来一个一个地处理它们,所以最后,您的计数器的值为 2,而不是 3。以确保这不会发生这种情况时,您明确传递这些术语值,当 ES 尝试更新它们时,将看到不同的序列号并拒绝您的请求。 为防止此类丢失更新、用例,始终建议发送明确的版本号。

问:- 我想弄清楚我是否需​​要发送这些值以获得最终一致性,或者我是否可以免费获得它而不发送这些值。

答案:- 这些与并发控制有关,与最终一致性无关。在 ES 中,写入总是发生在主分片上,但读取可能发生在任何副本上(可能包含过时的数据),这使得 ES 最终保持一致。

重要阅读

https://www.elastic.co/blog/elasticsearch-sequence-ids-6-0