首页 > 解决方案 > 乐观并发控制说明

问题描述

我是 ES7 新手,并试图理解乐观并发控制

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

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

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

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

标签: multithreadingelasticsearchdistributed-systemeventual-consistencyoptimistic-concurrency

解决方案


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

  1. _seq_no是为每个操作(更新、删除、索引)分配给 ES 文档的增量计数器,例如:- 第一次索引文档时,它将具有值 1,下一次更新将具有 2,下一次删除操作将具有三等。读取操作不会更新它。
  2. _primary_term也是一个增量计数器,但仅当副本分片因网络或任何其他故障而被提升为主分片时才会更改,因此如果集群中的一切都很好,则不会更改,但在某些故障和其他副本的情况下提升到初级,然后它会增加。

来到第一个问题,

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

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

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

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

重要阅读

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


推荐阅读