聊聊ElasticeSearch并发写的乐观锁机制
概述
ES的多客户端并发更新是基于乐观并发控制,通过版本号机制来实现冲突检测。
关键对象
ES的老版本是用过_version字段的版本号实现乐观锁的。现在新版增加了基于_seq_no与_primary_term字段,三个字段做乐观锁并发控制。

_version:标识文档的版本号,只有当前文档的更新,该字段才会累加;以文档为维度。
_seq_no:标识整个Index中的文档的版本号,只要Index中的文档有更新,就会累加该字段值;以Index为维度记录文档的操作顺序。
_primary_term:针对故障导致的主分片重启或主分片切换,每发生一次自增1;已分片为维度。
原先修改指定版本的请求参数是_version;目前修改指定版本的请求参数只能是
PUT user/_doc/1?if_seq_no=22&if_primary_term=2
乐观并发控制
乐观锁的操作主要就是两个步骤:
- 第一步:冲突检测。
- 第二步:数据更新。
参考乐观锁的版本号,JDK提供了一个AtomicStampedReference类,在CAS的基础上增加了一个Stamp(印戳或标记),使用这个印戳可以用来觉察数据是否发生变化,给数据带上了一种实效性的检验。
为什么要说到这个?网上很多资料就是一笔带过ES是通过乐观锁版本号来实现并发控制的,我就纳闷,仅仅通过版本号怎么实现的?ES的乐观锁实现就是类似AtomicStampedReference原理。其流程大致如下:
获取当前文档的最新版本号:在更新操作开始之前,Elasticsearch会获取当前文档的最新版本号。
检查版本号冲突:客户端在更新请求中提供了要更新文档的版本号,服务器会将客户端提供的版本号与实际文档的最新版本号进行比较。
如果客户端提供的版本号与实际文档的最新版本号一致,表示没有冲突,操作可以继续进行。
如果客户端提供的版本号与实际文档的最新版本号不一致,表示发生了版本冲突,更新操作会被拒绝并抛出
VersionConflictEngineException异常。原子性更新版本号:如果没有发生版本冲突,Elasticsearch会对文档的版本号进行原子性的更新。这意味着在更新过程中,其他并发的更新请求会被阻塞,直到当前更新操作完成。
更新文档内容:在版本号更新完成后,Elasticsearch会执行实际的文档更新操作,包括更新字段的值、添加或删除字段等。
这个过程就是一个典型的read-then-update的过程,ES保证原子事务。其实在并发更新下,哪怕是基于乐观锁多版本号控制,是一定要通过某种机制保证冲突检测与数据更新的原子性;并不是简单的一句多版本控制实现了乐观锁(是我自己较真了)。
翻了下GPT,如下是给出的回复。佐证了我的猜想(源码看了下,翻不动!)



冲突检测的解决
乐观锁出现版本冲突时,ES提供了相应的机制获取冲突
List<VersionConflict> conflicts = response.getGetResult().getConflicts();
同时还可以配置重试策略,因为一般情况下,都是可以通过重试解决的,ES中配置retry_on_confict即可。
聊聊ElasticeSearch并发写的乐观锁机制的更多相关文章
- Java并发编程(05):悲观锁和乐观锁机制
本文源码:GitHub·点这里 || GitEE·点这里 一.资源和加锁 1.场景描述 多线程并发访问同一个资源问题,假如线程A获取变量之后修改变量值,线程C在此时也获取变量值并且修改,两个线程同时并 ...
- sql server对并发的处理-乐观锁和悲观锁
https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...
- Java并发编程:Concurrent锁机制解析
Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...
- 乐观锁机制解决多层嵌套异步ajax问题
前言 在项目中我们通常需要使用ajax异步嵌套去请求数据并做数据的展示,当我们多次快速的多次的发起ajax,因为ajax是异步的,每个ajax触发回调的时间都是不可控的,这样就会造成前面发起的ajax ...
- sql server对并发的处理-乐观锁和悲观锁(转)
假如两个线程同时修改数据库同一条记录,就会导致后一条记录覆盖前一条,从而引发一些问题. 例如: 一个售票系统有一个余票数,客户端每调用一次出票方法,余票数就减一. 情景: 总共300张票,假设两个售票 ...
- sql server对并发的处理-乐观锁和悲观锁【粘】
假如两个线程同时修改数据库同一条记录,就会导致后一条记录覆盖前一条,从而引发一些问题. 例如: 一个售票系统有一个余票数,客户端每调用一次出票方法,余票数就减一. 情景: 总共300张票,假设两个售票 ...
- Hibernate逍遥游记-第15章处理并发问题-003乐观锁
1. 2. drop database if exists SAMPLEDB; create database SAMPLEDB; use SAMPLEDB; drop table if exists ...
- Java高并发情况下的锁机制优化
本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 1 public synchronized void syncMethod(){ 2 othercode ...
- 使用mysql乐观锁解决并发问题
案例说明: 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后提交.最后实际账户余额为1000 ...
- 使用mysql乐观锁解决并发问题思路
本文摘自网络,仅供个人学习之用 案例说明: 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...
随机推荐
- Android错误之--Error retrieving parent for item: No resource found that matches the given name 'Theme.A
改正错误 (虽然内容较少,但是还是选择单独占用一篇) 这个错误,可以说是困扰了我好久,然后就看到可以改变一下使用的Android版本,改成Android 4.0,然后就去试了试,发现真的就好了耶! 就 ...
- java顺序结构
java顺序结构 java的基本结构就是顺序结构,一句一句执行 package charpter2; public class ShunXu { public static void main(Str ...
- 基于OCR进行Bert独立语义纠错实践
摘要:本案例我们利用视频字幕识别中的文字检测与识别模型,增加预训练Bert进行纠错 本文分享自华为云社区<Bert特调OCR>,作者:杜甫盖房子. 做这个项目的初衷是发现图比较糊/检测框比 ...
- 碉堡!“万物皆可分”标记模型上线「GitHub 热点速览」
这周有个让人眼前一亮的图像识别模型 segment-anything,它能精细地框出所有可见物体,它标记出的物体边界线清晰可见.如此出色的模型,自然获得了不少人的赞赏,开源没几天,就拿下了 18k+ ...
- systemctl 命令设置开机自启动失败
哈喽大家好,我是咸鱼.今天跟大家分享一个关于 Linux 服务(service)相关的案例 案例现象 我在 3 月 31日的时候发表了一篇<shell 脚本之一键部署安装 Nginx> ...
- Golang爬虫:使用正则表达式解析HTML
之前所写的爬虫都是基于Python,而用Go语言实现的爬虫具有更高的性能. 第一个爬虫 使用http库,发起http请求 package main import ( "fmt" & ...
- Java的对象克隆
本节我们会讨论 Cloneable 接口,这个接口指示一个类提供了一个安全的 clone() 方法. Object 类提供的 clone() 方法是 "浅拷贝",并没有克隆对象中引 ...
- 31-dll
webpack.dll.js /** * 使用dll技术,对某些库(第三方库:jquery.react.vue...)进行单独打包 * 当你运行 webpack 时,默认查找 webpack.conf ...
- 【总结】从++i思考计算机原子性和线程安全
在C++中,++i被认为是一种原子性操作,即不可分割的.不可中断的整体.它能够确保对变量的修改完整且正确,从而避免了数据竞争等问题,提高了程序的并发性和可靠性.然而,有些人可能会将原子性和线程安全混淆 ...
- 【性能】JDK和Jmeter的安装与配置
一.JDK环境配置 1. 下载JDK 官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downl ...