我是ES7的新手,并试图理解乐观并发控制。
我想我理解,当我得到-请求一个文档并在以后的写请求中将其_seq_no和_primary_term值发送到同一个文档时,如果值不同,那么写将被完全忽略。
但是,在不发送_seq_no和_primary_term值的默认情况下,文档会发生什么情况呢?即使写入具有较旧的_seq_no和_primary_term值(因此使索引不一致),还是只有在值更新时才进行处理?
如果是前者,文件最终会不会是一致的?
我试图弄清楚,我是否需要发送这些值以获得最终的一致性,或者我是否免费获得这些值而不发送这些值。
发布于 2020-03-06 19:56:12
这是一个很好的分布式系统问题。为了便于阅读,让我把问题分解成子部分,甚至在解释什么是_seq_no和_primary_term之前,因为在ES站点上没有太多的解释。
_seq_no是为每个操作( update、delete、index)分配给ES文档的增量计数器,例如:-当您第一次索引一个文档时,它将有值1,下一个更新将有2,下一个删除操作将有三个等等。读取操作不会更新它。_primary_term也是一个增量计数器,但只有当副本碎片由于网络或任何其他故障被提升为主副本时才会更改,因此如果集群中的所有内容都很优秀,则不会更改,但是如果出现某些故障和其他副本升级为主副本,则会增加。关于第一个问题,
问:-,在默认情况下,在不发送_seq_no和_primary_term值的情况下,文档会发生什么情况?
Ans:-您可能丢失了update问题,假设您有一个正在更新的计数器,同时有2个请求将计数器值读取为1并试图增加1。现在,当您不显式地指定这些术语时,则由ES计算。现在,这两个请求同时到达ES,然后ES (主碎片)将通过增加序列号逐一处理它们,因此在最后,您的计数器将有值2,而不是3。为了确保这一情况不会发生,您将显式地传递这些术语值,当ES试图更新它们时,会看到不同的序列号并拒绝您的请求。为了防止这种丢失的更新,用例,它总是建议发送显式版本号。
Q:-我试图弄清楚我是需要发送这些值以获得最终的一致性,还是在不发送这些值的情况下免费获得这些值。。
答:-这些都是与并发控制相关的,没有必要处理最终的一致性问题。在ES中,写总是发生在主碎片上,但是读可以发生在任何副本(可能包含过时的数据),这使得ES最终一致。
重要读物
https://stackoverflow.com/questions/60564216
复制相似问题