惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
C
Check Point Blog
J
Java Code Geeks
腾讯CDC
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
量子位
Google DeepMind News
Google DeepMind News
I
InfoQ
The GitHub Blog
The GitHub Blog
aimingoo的专栏
aimingoo的专栏
N
Netflix TechBlog - Medium
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
T
The Blog of Author Tim Ferriss
小众软件
小众软件
博客园_首页
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
IT之家
IT之家

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400
elasticsearch实现乐观锁
祈雨的笔记 · 2019-04-27 · via 祈雨的笔记

elasticsearch的写操作是原子性的,可以通过如下两种方式实现es写操作的乐观锁。

基于_version

==version_type在elasticsearch6.x被移除,故该方法不适用于6.x版本==,详见https://www.elastic.co/guide/en/elasticsearch/reference/6.7/docs-update.html

1
2
3
4
5
6
PUT /user/user_type/1
{
"name": "tom",
"age": 18,
"doc_version": 1 // 自定义的文档版本号,用于乐观锁
}

只更新低版本的记录

1
2
3
4
5
6
PUT /user/user_type/1?version=2&version_type=external_gt
{
"name": "tom",
"age": 18,
"doc_version": 2
}

忽略版本号强制更新

1
2
3
4
5
6
PUT /user/user_type/1?version=3&version_type=force
{
"name": "tom",
"age": 18,
"doc_version": 3
}

基于script

1
2
3
4
5
6
PUT /user/user_type/1
{
"name": "tom",
"age": 18,
"doc_version": 1
}

只更新es中doc_version版本低的记录

1
2
3
4
5
6
7
8
9
10
11
12
POST /user/user_type/1/_update
{
"script": {
"source": "if(params.doc_force == true || ctx._source.doc_version < params.doc_version){for(entry in params.entrySet()){if (entry.getKey() != 'ctx') ctx._source[entry.getKey()] = entry.getValue();}}else{ctx.op = 'none'}",
"lang": "painless",
"params": {
"name": "tom",
"age": 19,
"doc_version": 19
}
}
}

忽略自定义版本号doc_version强制更新记录

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /user/user_type/1/_update
{
"script": {
"source": "if(params.doc_force == true || ctx._source.doc_version < params.doc_version){for(entry in params.entrySet()){if (entry.getKey() != 'ctx') ctx._source[entry.getKey()] = entry.getValue();}}else{ctx.op = 'none'}",
"lang": "painless",
"params": {
"name": "tom",
"age": 19,
"doc_version": 19,
"doc_force": true
}
}
}

注:读取script中的params的值时,需要过滤掉params.ctx,原因是es的painless脚本会自动向params中添加ctx,如果不过滤,则上述的更新语法会报如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[0l2AYvx][127.0.0.1:9300][indices:data/write/update[s]]"
}
],
"type": "illegal_argument_exception",
"reason": "Iterable object is self-referencing itself"
},
"status": 400
}

详见https://github.com/elastic/elasticsearch/pull/32096