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

推荐订阅源

M
MIT News - Artificial intelligence
雷峰网
雷峰网
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
博客园 - Franky
腾讯CDC
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
V
V2EX
N
Netflix TechBlog - Medium
量子位
Jina AI
Jina AI
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
爱范儿
爱范儿
博客园 - 叶小钗
D
Docker
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss

祈雨的笔记

安全多方计算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