今天介绍下elasticsearch中的乐观并发控制机制
并发控制
- 并发控制分为悲观的和乐观的,对应有我们的乐观锁和悲观锁。
- 悲观锁假设冲突随时发生,在处理前必须获得排他的锁再处理
- 乐观锁则认为不存在冲突,先处理,若最后发现在处理过程中发生了改变,则取消改变,回滚处理;
es的乐观并发控制
- Elasticsearch是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时也许 顺序是乱的 。 Elasticsearch 需要一种方法确保文档的旧版本不会覆盖新的版本
- 我们可以利用 version 号来确保 应用中相互冲突的变更不会导致数据丢失。我们通过指定想要修改文档的 version 号来达到这个目的。 如果该版本不是当前版本号,我们的请求将会失败
- 我们可以是使用其它数据库作为主要的数据存储,使用 Elasticsearch 做数据检索, 这意味着主数据库的所有更改发生时都需要被复制到 Elasticsearch ,如果多个进程负责这一数据同步,你可能遇到类似于之前描述的并发问题
- 如果你的主数据库已经有了版本号 — 或一个能作为版本号的字段值比如 timestamp — 那么你就可以在 Elasticsearch 中通过增加 version_type=external 到查询字符串的方式重用这些相同的版本号, 版本号必须是大于零的整数, 且小于 9.2E+18 — 一个 Java 中 long 类型的正值
- 外部版本号的处理方式和我们之前讨论的内部版本号的处理方式有些不同, Elasticsearch 不是检查当前 version 和请求中指定的版本号是否相同, 而是检查当前 version 是否 小于 指定的版本号。 如果请求成功,外部的版本号作为文档的新 version 进行存储
- 外部版本号不仅在索引和删除请求是可以指定,而且在 创建 新文档时也可以指定
总结
- 乐观控制在性能上通常更有优势,尤其是在读大部分都是读操作的场景
- 如果实际上确实存在很多冲突,乐观锁机制通常会退化,性能甚至低于悲观并发机制