multithreading - 乐观并发控制说明
问题描述
我是 ES7 新手,并试图理解乐观并发控制。
我想我明白,当我获取一个文档并在稍后的写入请求中将其_seq_no
和_primary_term
值发送到同一个文档时,如果值不同,则写入将被完全忽略。
但是在我不发送 _seq_no
and_primary_term
值的默认情况下,文档会发生什么?即使它具有较旧的值_seq_no
和_primary_term
值(因此使索引不一致),写入是否会通过,还是仅在值较新时才被处理?
如果是前者,文件最终会保持一致吗?
我试图弄清楚我是否需要发送这些值以获得最终的一致性,或者我是否在不发送这些值的情况下免费获得它。
解决方案
这是一个很棒的分布式系统问题。让我将问题分解为几个子部分以提高可读性,甚至在解释什么是之前_seq_no
,_primary_term
因为在 ES 网站上没有太多解释。
_seq_no
是为每个操作(更新、删除、索引)分配给 ES 文档的增量计数器,例如:- 第一次索引文档时,它将具有值 1,下一次更新将具有 2,下一次删除操作将具有三等。读取操作不会更新它。_primary_term
也是一个增量计数器,但仅当副本分片因网络或任何其他故障而被提升为主分片时才会更改,因此如果集群中的一切都很好,则不会更改,但在某些故障和其他副本的情况下提升到初级,然后它会增加。
来到第一个问题,
问:- 在我不发送 _seq_no 和 _primary_term 值的默认情况下,文档会发生什么情况?
回答:-您可能丢失了更新问题,假设您有一个正在更新的计数器,同时 2 个请求将计数器值读取为 1 并尝试增加 1。现在,当您没有明确指定上述这些术语时,那就是由 ES 计算。现在两个请求同时到达 ES,然后 ES(primary shard) 将通过增加序列号一个一个地处理它们,所以最后,你的计数器的值将是 2,而不是 3。确保这不会发生这种情况时,您会显式传递这些术语值,当 ES 尝试更新它们时会看到不同的序列号并拒绝您的请求。为了防止这种丢失的更新、用例,它总是建议发送明确的版本号。
问:- 我想弄清楚我是否需要发送这些值以获得最终的一致性,或者我是否可以在不发送这些值的情况下免费获得它。.
答:- 这些与并发控制有关,与最终一致性无关。在 ES 中,写入总是发生在主分片上,但读取可以发生在任何副本上(可能包含过时的数据),这使得 ES 最终保持一致。
重要阅读
推荐阅读
- excel - 如何使用 VBA 将单元格区域的颜色复制到其他单元格区域
- javascript - 当我单击浏览器第一页中的按钮时如何重新加载第二页?
- java - 为什么if条件语句中的几个逻辑或条件的顺序不一样,结果也不一样?
- node.js - 如何在不进行 npm install 的情况下更新 package-lock.json?
- c++ - 在命令终端中编译 ffmpeg 代码时遇到问题
- c# - C# - 即使在正确的通用约束之后,堆栈推送操作也不起作用
- c++ - 如何更改 QCompleter 的弹出列表的位置?
- python - 使用 imagekit 和 opencv 创建视频缩略图
- javascript - JavaScript Intellisense VScode [ts()] 的问题
- amazon-web-services - 通过 iam 策略中的标签限制 RDS rds:ModifyDBInstance 的问题