乐观并发控制澄清

Mor*_*ess 3 multithreading distributed-system eventual-consistency optimistic-concurrency elasticsearch

我是 ES7 的新手,正在尝试了解乐观并发控制

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

但是,在我不发送 和 _seq_no值的默认情况下,文档会发生什么情况_primary_term_seq_no即使它具有较旧的_primary_term值(因此使索引不一致),写入也会继续进行,还是仅在值较新时才被处理?

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

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

Ami*_*wal 6

这是一个很好的分布式系统问题。让我将问题分解为几个子部分以提高可读性,甚至在解释是什么之前_seq_no_primary_term因为 ES 网站上对此没有太多解释。

  1. _seq_no是为每个操作(更新、删除、索引)分配给 ES 文档的增量计数器,例如:- 第一次索引文档时,它将具有值 1,下次更新将具有值 2,下一个删除操作将具有值三等。读取操作不会更新它。
  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