搜索公众号,AmCoder干货及时送达👇
问题产生背景
众所周知,es经常被用于存储日志数据,其中在某些场景下,日志产生的时机不同,并且需要将多类具备关联关系的日志写入同一个document,就会带来同一个文档可能会被其它文档覆盖,或者missing等问题。
大家都知道es是不支持事务的,同时也不具备像关系型数据库那样可以关联查询的能力。所以我们如何将一个document在被完成后具备关联关系呢?我们需要遵循以下流程:
基础document创建------> 更新文档(_update/id) ------> 提交保存
而其中针对多类日志并发写入时,可能基础document结构还未创建,这是直接做update会直接报出document missing的问题,所以这就需要我们针对第一个接收到的日志数据在做update更新之前先做创建,并且需要文档锁级别的控制,才能保证在创建文档时不被后续涌入的数据直接update而报错document missing。我们通常使用
PUT http://ip:port/index/_doc/id?version=0&version_type=external
其中version代表当前document的版本号,所属范围时document级别,而version_type则为版本号类型,如果为external则需要后续更新的版本号需要比上一个版本号大,否则会报出异常。这就是我们今天要解决的问题,虽然用文档锁级别控制住了基础document的生成,但是后续的update操作无法控制由于并发而带来的版本号冲突问题。
问题表象
{
"error":{
"reason":"[20KB9MFIODLRPYET110091800X1169C685D4E1675646532216]: version conflict, required seqNo [3], primary term [1]. current document has seqNo [5] and primary term [1]",
"index_uuid":"eHmesKN8RNC3KUSEFQE0Tw",
"index":"logclient",
"type":"version_conflict_engine_exception",
"shard