首页 > 代码库 > 处理冲突(dealing with conflicts)

处理冲突(dealing with conflicts)

当我们使用index更新document的时候,首先读取原始的document,作出修改,然后一下在把新的document index到ES中。最后一次的操作因该是成功的,也就是说最近的一次index执行的document应该更新到ES,如果同时也有其他人在执行这个操作,那么他们的修改将会是丢失的。

通常这并不是个问题,例如,我们的主要的数据存储在关系性数据库中,我们只是把数据copy到ES以方便搜索,如有两个人同时对同一个documnet做出来小小的修改,或者偶尔的丢失数据对我们的业务不会造成什么影响。

然而有时候,这些丢失是非常重要的,试想一下,我们使用ES存储网上商店部件的库存数量,每次卖出一个部件,就要在ES中把库存数量减少一。一天,管理层决定要搞一个促销活动,忽然,每一秒我们都要卖出去好几个部件,设想一下有两个web进程,并行运行,两个进程同时在买一个部件,如下图:

Consequence of no concurrency control

如上图,web_2因为没有意识到stock_count的数据已经过期了,继续对stock_count进行修改,导致web_1修改的部件数量丢失了。这个结果就是我们以为部件的库存数量比实际的数量要多,客户会很失望,因为我们卖给客户的产品已经没有了。

数据变更的越是频繁,或者从读取数据到修改数据的间隔比较长,就越是回导致上述情况(数据改变丢失)的发生。

为了防止并发的修改数据导致的数据丢失,有两个途径可以解决这个问题:

1:悲观锁

这个方法被广泛的使用在关系性数据库,假设数据修改冲突这种情况会随时发生,所以就使用堵塞的方式保证线程按照顺序对数据进行修改以防止冲突。一个典型的例子就是在读取数据之前对数据加锁,保证只有一个得到锁的线程能改变数据。

2:乐观锁

ES中使用的就是乐观锁,假设冲突不会发生,并且尝试不会阻塞操作,然而如果相关的数据在读取和写入之间被修改了,这个修改就会导致失败。然后由应用程序决定怎么应对冲突。例如,可以使用新的数据再次尝试更新,或者把这个状况报告给用户。

 

原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/version-control.html