2019独角兽企业重金招聘Python工程师标准>>>

Elasticsearch 并发修改乐观锁 博客分类: 搜索引擎,爬虫

来自: http://blog.csdn.net//jiao_fuyou/article/details/50482117

版本控制的一个例子

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl -XPOST http://localhost:9200/test/test/1 -d '{"msg": "test"}'
{
     "_index" : "test" ,
     "_type" : "test" ,
     "_id" : "1" ,
     "_version" : 1,
     "created" : true
}
curl -XPOST http://localhost:9200/test/test/1 -d '{"msg": "test"}'
{
     "_index" : "test" ,
     "_type" : "test" ,
     "_id" : "1" ,
     "_version" : 2,
     "created" : true
}
curl -XPOST http://localhost:9200/test/test/1?version=1 -d '{"msg": "test"}'
{
     "error" : "RemoteTransportException[[elasticsearch_226][inet[/172.16.18.226:9300]][indices:data/write/index]]; nested: VersionConflictEngineException[[test][0] [test][1]: version conflict, current [4], provided [1]]; " ,
     "status" : 409
}

提示:版本冲突

使用外部系统提供的版本号

Elasticsearch 的乐观锁,可以使用外部系统提供的版本号:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl -XPOST http://localhost:9200/test/test/1?version=10&version_type=external -d '{"msg": "test"}'
{
     "_index" : "test" ,
     "_type" : "test" ,
     "_id" : "1" ,
     "_version" : 10,
     "created" : true
}
curl -XPOST http://localhost:9200/test/test/1?version=9&version_type=external -d '{"msg": "test"}'
{
     "error" : "VersionConflictEngineException[[test][0] [test][1]: version conflict, current [10], provided [9]]" ,
     "status" : 409
}

这时Elasticsearch将只检查提供的版本是否比当前保存在索引中的版本大(大多少不重要),如果是成功,否则失败。

Elasticsearch内部版本号

在Elasticsearch中,更新请求实际上是分为两个阶段,获取文档,修改文档,然后保存文档。
那么当两个更新请求同时要修改文档的时候,系统乐观的认为不会有两个并发请求对一个系统操作。
文档原本的版本为1,请求A获取了version为1的文档,请求B也获取了version为1的文档,然后请求A修改完文档后,并且先执行了保存操作,这个时候,系统中的文档version变为了2。
这个时候,B再执行保存操作的时候,告诉系统我要修改version为1的文档。系统就会抛出一个错误,说文档版本不匹配。然后这个错误由应用程序自己来进行控制。
这种机制在请求量大的时候会比悲观锁机制好。但是缺点是需要程序处理版本冲突错误,可能一般的方法是封装更新操作,并且设置重复重试次数。

注意这里的更新指的是:

?
1
curl -XPOST http://localhost:9200/test/test/1/_update -d '{"msg": "test"}'

而不是:

?
1
curl -XPOST http://localhost:9200/test/test/1 -d '{"msg": "test"}'

这个是create,这种在ES内部没有乐观锁的概念,是直接覆盖,这种想解决数据被覆盖,就要显示的带着version

下面的程序,并发6个进程同时批量更新一个文档,在结果能看到有的请求出错了,返回版本冲突。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
require_once dirname(__FILE__). '/../shjf/vendor/autoload.php' ;
$client = new Elasticsearch\Client([ 'hosts' => [ '172.16.18.226:9200' ]]);
for ($i=0;$i<5;$i++){   
     if (pcntl_fork() == 0) break;
}
$params=[
     'index' => 'test' ,
     'type'  => 'test' ,
     'body' => [],
]; 
for ($i=0;$i<1;$i++){
     $params[ 'body' ][] = [ 'update' => [ '_id' => 111]];
     $params[ 'body' ][] = [ "doc" => [ "id" => $i]];
}
try
{
     $result = $client->bulk($params);
     var_dump($result) . "\n" ;
}
catch(Exception $e)
{
     echo $e->getMessage() . "\n" ;
     $info = $client->transport->getLastConnection()->getLastRequestInfo();
     print_r($info);
     exit;
}
echo "end\n" ;
?>
{
   "took" :1,
   "errors" : true ,
   "items" :[
     { "update" : {
         "_index" : "test" ,
         "_type" : "test" ,
         "_id" : "111" ,
         "status" :409,
         "error" : "VersionConflictEngineException[[test][0] [test][111]: version conflict, current [3], provided [2]]" }
     }
   ]
}

参考资料:

  • Elasticsearch官网:

    • https://www.elastic.co/guide/en/elasticsearch/reference/2.1/docs-update.html
    • https://www.elastic.co/guide/en/elasticsearch/guide/master/partial-updates.html
    • https://www.elastic.co/guide/en/elasticsearch/guide/master/optimistic-concurrency-control.html
  • 《Elasticsearch权威指南》处理冲突
    • http://download.csdn.net/detail/xtjsxtj/9398862

转载于:https://my.oschina.net/xiaominmin/blog/1599475

Elasticsearch 并发修改乐观锁相关推荐

  1. Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

    Java并发问题–乐观锁与悲观锁以及乐观锁的一种实现方式-CAS </h1><div class="clear"></div><div c ...

  2. Java并发:乐观锁

    简介 悲观锁和乐观锁都属于比较抽象的概念: 我们可以用拟人的手法来想象一下: 悲观锁:像有些人,凡事都往坏的想,做最坏的打算:在java中就表现为,总是认为其他线程会去修改共享数据,所以每次操作共享数 ...

  3. 数据库 并发更新之乐观锁和悲观锁

    文章目录 1. 问题引出 2. 数据库悲观锁解决并发更新 3. 数据库乐观锁解决并发更新 4. 乐观锁 CAS 的 ABA 问题 5. 拓展思考 5.1. 悲观锁和排他锁.乐观锁和 CAS 分别有什么 ...

  4. java学习系列2(并发锁问题-乐观锁与悲观锁以及乐观锁的一种实现方式-CAS)

    Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别 ...

  5. [精选]MySQL的各种锁(表锁,行锁,悲观锁,乐观锁,间隙锁,死锁)

    不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下),即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的.因为数据库隐式帮我们 ...

  6. MySQL:行锁、表锁、乐观锁、悲观锁、读锁、写锁

    1.锁的分类 1.1从对数据操作的类型来分 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响. 结论1: --如果某一个会话 对A表加了read锁,则 该会话 可以对A表进行读操作 ...

  7. Django - ORM - 事务, 乐观锁, 悲观锁

    事务 概念 Transaction 事务:一个最小的不可再分的工作单元:通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元) 一个完整的业务需要批量的DML(inser ...

  8. python乐观锁和悲观锁

    使用场景: 你银行卡现在100块, A地花了10块,然后A地停电,会有延迟扣款 然后你的公司给你同时发了200工资, 如果公司先査你的钱100,同时A地查也是查到100 你公司先update了,你现在 ...

  9. 悲观锁、乐观锁以及分布式锁

    1.单机应用乐观锁悲观锁,select 时怎么加排它锁? 1.1悲观锁(Pessimistic Lock): 悲观锁特点:先获取锁,再进行业务操作. 即"悲观"的认为获取锁是非常有 ...

最新文章

  1. MM模块几个移动类型之间的区别
  2. 常用API-2(字符串与数组)
  3. Mysql游标循环遍历
  4. python获取依赖包和安装依赖包
  5. ·必须《飞鸽~飞鸽传书》
  6. MYSQL常用操作(一)之设置ROOT密码,连接,常用命令
  7. 基于实数编码的参数自适应遗传算法(matlab代码)
  8. 浮动div中的图片垂直居中
  9. android studio技巧之设置monitor窗口模式查看logcat
  10. 2021年PMP考试最新通关宝典
  11. 《深入浅出WPF》——事件学习
  12. PHP+MYSQL 用户注册登录代码
  13. MySQL优化器成本记录表
  14. 2号 CAD常用快捷键
  15. 推荐几个好用的API测试工具?我保证你一定会喜欢的
  16. Cesium自定义几何体
  17. Ubuntu18.04上编译并跑通VINS-Fusion
  18. Photoshop去图片水印——适用复杂图片上有水印
  19. 朴素贝叶斯分类算法python代码
  20. flex布局的justify-content属性写法注意事项

热门文章

  1. centos安装过程中gpt报错解决方案
  2. Lync Server 2010 权限相关
  3. Struts提供我们方便地将客户端上传的文件处理
  4. C#读取ACCESS数据
  5. 《Pro ASP.NET MVC 3 Framework》学习笔记之十四【示例项目SportsStore】
  6. 动手做webserver的核心之http解析
  7. HDU 1285:确定比赛名次(拓扑排序)
  8. 填坑 ---- arcgis api for javascript 加载天地图
  9. ffmpeg -acodec列表
  10. Linux系统的账号管理