文章目录
1. 基于乐观锁的并发控制
Elasticsearch是分布式的。创建,更新或删除文档时,必须将文档的新版本复制到群集中的其他节点。 Elasticsearch也是异步和并发的,这意味着这些复制请求是并行发送的,并且可能不按顺序到达其目的地。 Elasticsearch需要一种方法来确保文档的old version永远不会覆盖 a newer version。
为确保文档的较旧版本不会覆盖较新的版本,对文档执行的每项操作均由主分片分配一个sequence number(序号),来协调更改。每次操作都会增加sequence number 序列号,因此可以确保较新的操作具有比较旧的操作更高的序列号。然后,Elasticsearch可以使用操作的序列号来确保分配给它的序列号较小的更改不会覆盖较新的文档版本。
For example, the following indexing command will create a document and assign it an initial sequence number and primary term:
举例,如下的index操作create一个doc并赋予一个初始的sequence number和primary term
PUT products/_doc/1567
{
"product" : "r2d2",
"details" : "A resourceful astromech droid"
}
{
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 1
},
"_index" : "products",
"_type" : "_doc",
"_id" : "1567",
"_version" : 1,
"_seq_no" : 362,
"_primary_term" : 2,
"result" : "created"
}
Elasticsearch会跟踪上次操作的sequence number序列号和primary term,。sequence number序列号和primary term会在GET API的响应中的_seq_no和_primary_term字段中返回:
GET products/_doc/1567
returns:
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1567",
"_version" : 1,
"_seq_no" : 362,
"_primary_term" : 2,
"found": true,
"_source" : {
"product" : "r2d2",
"details" : "A resourceful astromech droid"
}
}
但是search api中默认不会返回,你可以通过一些设置来让他返回。
Note: The Search API can return the _seq_no and _primary_term for each search hit by setting seq_no_primary_term parameter.
sequence number序列号和primary term唯一的标识了一次change。通过记下返回的序列号和主要术语,可以确保仅在从你的search 请求拿到对应的doc之后到你要对其做修改之前,没有任何人对该文档做过修改,在这种情况下你的修改才更改该文档。这可以通过设置Index API或Delete API的if_seq_no和if_primary_term参数来完成。
For example, the following indexing call will make sure to add a tag to the document without losing any potential change to the description or an addition of another tag by another API:
PUT products/_doc/1567?if_seq_no=362&if_primary_term=2
{
"product" : "r2d2",
"details" : "A resourceful astromech droid",
"tags": ["droid"]
}