乐观的并发控制(optimistic concurrency control)
2014-05-15 22:38
477 查看
ES是分布式的。当document被create,update,或者delete,这个document的新版本就会冗余到cluster的其他node中。ES是异步和并发的,意味着冗余请求也是并行进行的,并且请求到达也是无次序的。因此需要一个方式保证老版本的document不能重写新版本的数据。
如上所述,当我们讨论index,get和delete请求,我们指出每个document都有一个_version号,这个号码随着document的变化而增长。ES使用这个_version保证document的变化在一个正确的顺序上执行,如果一个旧版本的document落后于新的版本,这个旧版本就会被忽略。
我们能利用这个_version号保证由我们的应用造成的数据冲突不会导致数据丢失。通过指定想要修改的document的version号达到这个目的。如果指定的version不再是当前的版本,这个请求将会失败。
创建一个新的blog:
返回的消息体告诉我们,新创建的document的_version号是1,设想一下,我们要编辑这个document:我们把这个数据加载到web form,作出修改,然后保存。
首先检索这个document:
这个相应的消息体包括了_version号码
现在,通过重新index这个document来保存修改,指定我们要修改的version:
标记1表示试图更新的document的version是1,如果document是1就更新成功。
这个请求是成功的,相应消息体表明_version已经增加到了2:
然而,如果我们再次重复执行并且依然指定version=1,ES将会用409这个HTTP消息头应答这个冲突,并且消息体如下:
这个表明当前的document的_version是2,但是我们要更新的是1。
我们要做的事情依赖于应用的需求。我们可以告诉用户有人已经修改了这个document,如果想尝试修改这个数据就要重新审视新的修改,当然,我们也可以检索这个document并且向用户报告这个改变,就像上面提到的stock_count一样。
所有的API,无论是update或者delete一个document,都可以携带一个version参数,这个允许你应用乐观的并发控制你代码中最有意义的部分。
使用其他系统的version
一个常见的现象就是,使用其他数据库作为主数据库,ES作为搜索数据库,当主数据库中的数据发生变化,需要把这些变化复制到ES中,如果多个进程同步的的相应这个数据,那么这个数据就会出现上述的并发问题。
如果主数据库已经有version号,或者类似于时间戳的能作为version号的字段,在ES中也可以通过使用version_type=external使用这个字段作为version_号。version必须是比零大的整形,并且要比9.2e+18小——Java中的正long型数据。
其他系统version号使用起来和上面的略有不同——ES中检查的请求中的version号要和数据库中的version要一样——ES中检查请求中的external的version要比数据库中的version要大。如果请求成功,这个大的external就会写入作为document的新的version。
扩展的version不但能用在index,delete,而起能用到创建一个新的cocument。
例如使用external version是5创建一个新的blog:
在相应中就会看到_version是5:
然后指定version是10进行更新:
相应成功后_version就成了10:
就像以前看到的一样,如果你重新执行这个请求,就会因为冲突而导致失败,因为请求指定的external version要不比当前的高。
原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html#optimistic-concurrency-control
如上所述,当我们讨论index,get和delete请求,我们指出每个document都有一个_version号,这个号码随着document的变化而增长。ES使用这个_version保证document的变化在一个正确的顺序上执行,如果一个旧版本的document落后于新的版本,这个旧版本就会被忽略。
我们能利用这个_version号保证由我们的应用造成的数据冲突不会导致数据丢失。通过指定想要修改的document的version号达到这个目的。如果指定的version不再是当前的版本,这个请求将会失败。
创建一个新的blog:
PUT /website/blog/1/_create { "title":"My first blog entry", "text": "Just trying this out..." }
返回的消息体告诉我们,新创建的document的_version号是1,设想一下,我们要编辑这个document:我们把这个数据加载到web form,作出修改,然后保存。
首先检索这个document:
GET /website/blog/1
这个相应的消息体包括了_version号码
{ "_index": "website", "_type": "blog", "_id": "1", "_version":1, "found": true, "_source": { "title":"My first blog entry", "text": "Just trying this out..." } }
现在,通过重新index这个document来保存修改,指定我们要修改的version:
PUT /website/blog/1?version=1 { "title":"My first blog entry", "text": "Starting to get the hang of this..." }
标记1表示试图更新的document的version是1,如果document是1就更新成功。
这个请求是成功的,相应消息体表明_version已经增加到了2:
{ "_index": "website", "_type": "blog", "_id": "1", "_version":2 "created": false }
然而,如果我们再次重复执行并且依然指定version=1,ES将会用409这个HTTP消息头应答这个冲突,并且消息体如下:
{ "error":"VersionConflictEngineException[[website][2][blog][1]: version conflict, current [2], provided [1]]", "status":409 }
这个表明当前的document的_version是2,但是我们要更新的是1。
我们要做的事情依赖于应用的需求。我们可以告诉用户有人已经修改了这个document,如果想尝试修改这个数据就要重新审视新的修改,当然,我们也可以检索这个document并且向用户报告这个改变,就像上面提到的stock_count一样。
所有的API,无论是update或者delete一个document,都可以携带一个version参数,这个允许你应用乐观的并发控制你代码中最有意义的部分。
使用其他系统的version
一个常见的现象就是,使用其他数据库作为主数据库,ES作为搜索数据库,当主数据库中的数据发生变化,需要把这些变化复制到ES中,如果多个进程同步的的相应这个数据,那么这个数据就会出现上述的并发问题。
如果主数据库已经有version号,或者类似于时间戳的能作为version号的字段,在ES中也可以通过使用version_type=external使用这个字段作为version_号。version必须是比零大的整形,并且要比9.2e+18小——Java中的正long型数据。
其他系统version号使用起来和上面的略有不同——ES中检查的请求中的version号要和数据库中的version要一样——ES中检查请求中的external的version要比数据库中的version要大。如果请求成功,这个大的external就会写入作为document的新的version。
扩展的version不但能用在index,delete,而起能用到创建一个新的cocument。
例如使用external version是5创建一个新的blog:
PUT /website/blog/2?version=5&version_type=external { "title":"My first external blog entry", "text": "Starting to get the hang of this..." }
在相应中就会看到_version是5:
{ "_index": "website", "_type": "blog", "_id": "2", "_version":5, "created": true }
然后指定version是10进行更新:
PUT /website/blog/2?version=10&version_type=external { "title":"My first external blog entry", "text": "This is a piece of cake..." }
相应成功后_version就成了10:
{ "_index": "website", "_type": "blog", "_id": "2", "_version":10, "created": false }
就像以前看到的一样,如果你重新执行这个请求,就会因为冲突而导致失败,因为请求指定的external version要不比当前的高。
原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html#optimistic-concurrency-control
相关文章推荐
- MySQL 的乐观并发控制Optimistic concurrency control
- Multi-Version Concurrency Control 多版本并发控制
- Multi-Version Concurrency Control 多版本并发控制
- MVCC (Multiversion Concurrency Control) 多并发版本控制
- 多版本并发控制MVCC(Multi-Version Concurrency Control )
- 数据访问模式:数据并发控制(Data Concurrency Control)
- MVCC(多版本并发控制,MultiVersion Concurrency Control)
- 数据访问模式:数据并发控制(Data Concurrency Control)
- EF的乐观并发控制
- ElasticSearch13:partial update原理以及乐观锁并发控制
- 高并发控制解决方案乐观并发控制和悲观并发控制总结
- ES权威指南[官方文档学习笔记]-37 optimistic concurrency control
- hibernate之控制并发访问(乐观并发控制之理解乐观策略)
- MySQL数据库优化(三)——MySQL悲观锁&&乐观锁(并发控制)
- 并发控制中的乐观锁与悲观锁
- Dynamics CRM 2015 Update 1 系列(6): 并发执行优化 - Optimistic Concurrency
- 第18/24周 乐观并发控制(Optimistic Concurrency)
- spring控制并发数的工具类ConcurrencyThrottleSupport和ConcurrencyThrottleInterceptor
- Oracle并发控制中的乐观锁
- Optimistic vs Multi Version Concurrency Control - Differences?