Elasticsearch(处理冲突)

来源:互联网 发布:json 中括号 编辑:程序博客网 时间:2024/05/29 08:30

处理冲突

当使用index API更新文档的时候,我们读取原始文档,做修改,然后将整个文档(whole document)一次性的重新索引。最近的索引请求会生效-Elasticsearch中只存储最后被索引的任何文档。如果其他人同时也修改了这个文档,他们的修改,将会丢失。

例子:

一天,老板决定做一个促销。瞬间,我们每秒就销售了几个商品。想象两个同时运行的web进程,两者同时处理一件商品。


web_1让stock_count失效是因为web_2没有察觉到stock_count的拷贝已经过期(web_1取数据,减一后更新了stock_count。但是在stock_count更新前web_2就拿到了数据,这个数据已经过期,当web_2再回来更新stock_cunt时这个数字就会出错。这样就会造成看似卖了两件东西,其实只卖了一件东西的幻读。)
变化越是频繁,或读取和更新的时间越长,越容易丢失我们的更改

在数据库中,有两种通用的方法确保在并发更新时修改不丢失

悲观并发控制(Pessimistic concurrency control)

这在关系型数据库中被广泛应用,假如冲突的更改经常发生,为了解决冲突我们把访问区块化。典型的例子是在读一行数据前锁定这行,然后确保只有加锁的那个线程才可以修改这行数据

乐观并发控制(Optimistic 从currency control)

被Elasticsearch使用,假如冲突不经常发生,也不区块化,然而,如果在读写过程中数据发生了变化,更新操作将失败。这时候程序决定在失败后如何解决冲突。实际情况,可以重新尝试,刷新数据(重新读取)或者直接反馈给用户。

乐观并发控制(Optimistic 从currency control)

Elasticsearch是分布式的。当文档被创建、更新或删除、文档的新版本会被复制到集群的其它节点。Elasticsearch即是同步也是异步的,意思是这些复制请求都是平行发送的,并无序(out of sequence的到目的地。这就需要一种确保老版本永远不会覆盖新版本。
我们指出的每一个文档都有一个_version号码,这个号码在文档被改变时加一。Elasticsearch使用这个_version保证所有的修改都被正确的排序。当旧版本在新版本出现之后,它就会被忽略。

我们需要做什么取决于程序的需求。我们可以告知用户其他人修改了文档,你应该在保存之前再看一下。
所有的更新和删除文档的请求都接收version参数,它可以允许在你的代码中增加乐观锁控制

使用外部版本控制
一种常见的结构是使用一些其它的数据库作为主数据,然后使用Elasticsearch搜素数据,这意味着所有的主数据库发生改变,就要将其拷贝到Elasticsearch中。如果多个进程负责这些数据的同步,就会遇到上面提到的并发问题。

如果主数据有版本字段--或一些类似于timestamp等可以用于版本控制的字段--是你可以在Elasticsearch的查询字符串后面添加version_tyoe=external来使用这些版本号。版本号必须是整数,大于零小于9.2e+18-----java中的正long

外部版本号与之前的内部版本号在处理的时候有些不同。他不再检查_version是否与请求中指定的一致,而检查是否小于指定的版本。如果请求成功,外部的版本号就会本存储到_version中。


原创粉丝点击