当两个进程同时写入时,如何在同一个键上修复ElasticSearch冲突

时间:2016-03-23 21:21:48

标签: elasticsearch

我有多个进程同时向ES写入数据,同时两个进程可能同时使用不同的值写入相同的密钥,导致异常如下:

"error" : "VersionConflictEngineException[[website][2] [blog][1]:
             version conflict, current [2], provided [1]]",
"status" : 409

我怎么能解决上述问题,因为我必须保留多个进程。

3 个答案:

答案 0 :(得分:15)

抛出

def mergeList(lst1,lst2): lst3 = [item for t in zip(lst1, lst2) for item in t] if len(lst2) > len(lst1): lst3 += lst2[len(lst1):] if len(lst1) > len(lst2): lst3 += lst1[len(lst2):] return lst3 以防止数据丢失。 elasticsearch中的每个文档都有一个VersionConflictEngineException数字,只要文档发生变化,该数字就会递增。

从ES查询文档时,响应还包括该文档的版本。当您更新相同的文档并提供版本时,预计索引中已存在具有相同版本的文档。

如果当前版本大于更新请求中的版本,我们现在得到的是冲突,HTTP错误代码为409且_version

在您当前的情况中,

  

版本冲突,当前2,提供1

ES中的当前版本是2,而在您的请求中是1,这意味着其他一些线程已经修改了文档,您的更改正在尝试覆盖该文档。

如果出现VersionConflictEngineException,您应该重新获取文档并尝试使用最新更新版本再次更新。

是否使用versioning / Optimistic Concurrency Control取决于应用程序。如果您可以忍受数据丢失,则可以避免在更新请求中传递版本。

答案 1 :(得分:0)

ES提供了使用retry_on_conflict查询参数的功能。

  

指定发生冲突时应重试该操作多少次。默认值:0。

如果您有多个可以同时使用同一文档的并行脚本,则可以使用此参数。

例如: 您有一条推文索引。还有5个将与此索引配合使用的过程。所有5个脚本可能都可以在同一文档中使用(有些鸣叫)。在这种情况下,您可以使用...&retry_on_conflict=6参数。为什么是6? 5个流程+ 1(还有一些余地)。因此,如果发生冲突,ES将尝试最多重新更新文档6次。

答案 2 :(得分:0)

您还可以通过使用弹性搜索外部版本控制系统对此进行计划,并按如下所述手动维护文档版本

enter image description here