序列号已在ES 6.0.0中引入。在该版本发布之前,blog article中对它们进行了很好的解释。
但总而言之,
-
version
是一个序列号,用于计算文档更新的时间
-
_seq_no
是一个序列号,用于计算索引上发生的操作次数
因此,如果您创建第二个文档,您会发现version
和_seq_no
将有所不同。
让我们创建三个文档:
POST test/_doc/_bulk
{"index": {}}
{"test": 1}
{"index": {}}
{"test": 2}
{"index": {}}
{"test": 3}
在响应中,您将在下面获得有效负载。
{
"took" : 166,"errors" : false,"items" : [
{
"index" : {
"_index" : "test","_type" : "_doc","_id" : "d2zbSW4BJvP7VWZfYMwQ","_version" : 1,"result" : "created","_shards" : {
"total" : 2,"successful" : 1,"failed" : 0
},"_seq_no" : 0,"_primary_term" : 1,"status" : 201
}
},{
"index" : {
"_index" : "test","_id" : "eGzbSW4BJvP7VWZfYMwQ","_seq_no" : 1,"_id" : "eWzbSW4BJvP7VWZfYMwQ","_seq_no" : 2,"status" : 201
}
}
]
}
如您所见:
- 对于所有文档,版本均为1
- 对于文档1,
_seq_no
为0(第一次索引操作)
- 对于文档2,
_seq_no
为1(第二索引操作)
- 对于文档3,
_seq_no
为2(第三索引操作)
,
Elasticsearch文档是不可变的
Elasticsearch
文档是不可变的,这意味着无论您何时更新文档,都将创建该文档的新版本,无论您是否使用PUT
(更新整个文档)或POST
(更新文档的某些部分)。
每个新创建的文档将获得一个新的递增的版本,该字段由_version
字段标识:
{
"_index": "movies","_type": "_doc","_id": "109487","_version": 14,"result": "updated","_shards": {
"total": 2,"successful": 1,"failed": 0
},"_seq_no": 17,"_primary_term": 7
}
博客网站
假设您有一个博客网站,并且有 2 个用户同时点击了ID为 1 的同一博客帖子 :
GET https://myblog.com/posts/1
回到Elasticsearch
,post
文档中有一个名为view_count
的字段,该字段存储了查看的总数(查看过该帖子的次数 )。
要递增view_count
,您必须发送一个GET
请求以读取当前值:
GET /posts/_doc/1
{
"_index": "movies","_version": 12,"_seq_no": 15,"_primary_term": 7,"found": true,"_source": {
"post": "Lorem ipsum ...","title": "My title","published_at": "2020-01-01","view_count": 10
}
}
然后,通过将返回值(从view_count
开始)增加 1 ,来更新帖子ID 1 的GET
:
PUT /posts/_doc/1/_update
{
"doc": {
"view_count": 11
}
}
这里有问题。
由于两个用户都同时访问了相同的帖子页面,因此他们将获得10
的价值。
如您在此处看到的,存储了值 11 ,但这是不正确的,因为我们两次更新了文档(记住2个用户同时点击了帖子ID ),因此该值应为 12 。
但是为什么呢?这是因为两个用户在读取10
时都获得了值view_count
。
那么,我们如何解决这个问题?
幸运的是,Elasticsearch使用了称为乐观并发控制( OCC )(Optimistic concurrency control - Wikipedia)的东西。
为确保需要更新最近的文档,我们将if_primary_term
值与if_seq_no
值一起发送(从GET
请求中获取):
POST /posts/_update/1?if_primary_term=1&if_seq_no=10
就这样。
本文链接:https://www.f2er.com/3139774.html