通过版本来实现并发控制

516 阅读1分钟

如果同一时刻多次更新都在执行,将面临并发问题。Elasticsearch支持并发控制,为每篇文档设置了一个版本号。乐观锁,如果更新发生冲突,目前的更新会失败

POST /secisland/_doc/1
{
  "name":"张三",
  "age": 23
}
# 查询时显示version
GET /secisland/_search?q=age:23&version=true
GET /secisland/_doc/1
​
{
  "_index" : "secisland",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 46,
  "_seq_no" : 45,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "张三",
    "age" : 24
  }
}
​

version

冲突发生时自动重试更新retry_on_conflict

POST /secisland/_update/1?retry_on_conflict=2
{
  "script": "ctx._source.age+=1"
}
​

seq_no

index文档时使用版本号,而不使用更新API。这种操作会覆盖现有文档。可以使用seq_no和primary_term实现并发控制

seq_no: The sequence number is increased with each operation and thus newer operations are guaranteed to have a higher sequence number than older operations. Elasticsearch can then use the sequence number of operations to make sure a newer document version is never overridden by a change that has a smaller sequence number assigned to it.

primary_term: 每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1。

PUT /secisland/_doc/1?if_seq_no=44&if_primary_term=1
{
"name":"张三",
"age": 23
}
​

使用外部版本

如果数据源是另一个数据存储,也许那里有版本控制系统。可以使用version=xx&version_type=external实现外部版本控制