我有多个进程同时向ES写入数据,同时两个进程可能同时使用不同的值写入相同的密钥,导致异常如下:
"error" : "VersionConflictEngineException[[website][2] [blog][1]:
version conflict, current [2], provided [1]]",
"status" : 409
我怎么能解决上述问题,因为我必须保留多个进程。
答案 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
在您当前的情况中,
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)