文章目录
- 利用external对版本号进行外部控制
- 利用if_seq_no和if_primary_term作为唯一标识来避免版本冲突
- ES中的文档是不可变更的。如果你更新一个文档,会将就文档标记为删除,同时增加一个全新的文档。同时文是的version字段加1
- 内部版本控制
- If_seq_no + If_primary_term
- 使用外部版本(使用其他数据库作为主要数据存储)
- version + version_type=external
利用external对版本号进行外部控制
当使用external版本类型时,Elasticsearch在处理索引请求时会对比传入文档的版本号和已存储文档的版本号。如果传入的版本号大于已存储的,就表明这是一个新版本的文档,Elasticsearch则会执行索引操作并更新文档的版本号。然而,如果传入的版本号小于或等于已有版本号,这就意味着可能存在并发修改的问题,Elasticsearch会认为发生了版本冲突,索引操作将被拒绝。
下面进行实战演练。在没有开启external模式的情况下执行如下命令。
DELETE products
PUT products
PUT products/_doc/1
{
"title":"iphone",
"count":100
}
GET products/_doc/1
PUT products/_doc/1?version=2
{
"title":"iphone",
"count":100
}
这表明内部版本控制不能使用乐观锁,也就是说,不能直接使用version,而需要使用if_seq_no和if_primary_term
如果开启了external模式,则执行如下命令。
PUT products/_doc/1?version=2&version_type=external
{
"title":"iphone",
"count":100
}
与不用external相比,使用external后可以基于version进行文档更新操作。external_gt和external_gte在Elasticsearch中被用于控制版本冲突。简单来说,利用这种方式,只有当给定的版本号大于(gt)或大于等于(gte)当前版本号时,才会执行更新或索引操作。
利用if_seq_no和if_primary_term作为唯一标识来避免版本冲突
DELETE products
PUT products
PUT products/_doc/1
{
"title":"iphone",
"count":100
}
GET products/_doc/1
PUT products/_doc/1?if_seq_no=1&if_primary_term=1
{
"title":"iphone",
"count":100
}
在执行索引写入操作时,Elasticsearch会检查传入的if_seq_no和if_primary_term是否与最后一次修改文档的序列号(seq no)和主要项(primary term)匹配。这两个参数共同提供了一种强大的控制机制,确保只有当所提供的版本信息与文档的最新状态一致时,才会执行写入操作。