Bootstrap

Elasticsearch(五)——乐观锁并发控制 if_seq_no 和 if_primary_term 详解

if_seq_no 和 if_primary_term 详解

1 创建一简单文档
2. 修改文档,_seq_no会+1
3. 修改文档,带上if_seq_no和if_primary_term
4. 修改文档,模拟并发
5. 删除文档,_seq_no还是会+1
6. seq_no递增属于整个index,而不是单个文档

if_seq_no 和 if_primary_term 是用来并发控制,他们和version不同,version属于当个文档,而seq_no属于整个index。

1 创建一简单文档

PUT /pigg_test/_doc/1
{
  "name": "王哥",
  "age": 22,
  "interest": ["music", "food"]
}

返回结果如下:

注意最后2个值,_seq_no在文档跟新一次后都会+1,_primary_term表示文档所在主分片的编号

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

用GET查看文档

GET pigg_test/_doc/1
{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "冬哥",
    "age" : 33,
    "interest" : [
      "music",
      "food"
    ]
  }
}

2. 修改文档,_seq_no会+1

PUT /pigg_test/_doc/1
{
  "name": "隔壁老王",
  "age": 18,
  "interest": ["music", "food"]
}

返回如下:

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

3. 修改文档,带上if_seq_no和if_primary_term

修改时,if_seq_no和if_primary_term设置为被修改前的当前值,上面第2步结果_seq_no=1,所以这里要设置if_seq_no=1,分片也没有换,所以if_primary_term=1

PUT /pigg_test/_doc/1?if_seq_no=1&if_primary_term=1
{
  "name": "老王",
  "age": 18,
  "interest": ["music", "food"]
}

返回说明修改成功,_seq_no又+1,变成了2

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

4. 修改文档,模拟并发

PUT /pigg_test/_doc/1?if_seq_no=1&if_primary_term=1
{
  "name": "小王哥",
  "age": 22,
  "interest": ["music", "food"]
}

因为seq_no已经变成了2,但是上面请求时还是if_seq_no=1,所以会报错,错误原因详细看reason的值。

{
  "error" : {
    "root_cause" : [
      {
        "type" : "version_conflict_engine_exception",
        "reason" : "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
        "index_uuid" : "iGtCA6A_TyeQeHrMM9_c7A",
        "shard" : "0",
        "index" : "pigg_test"
      }
    ],
    "type" : "version_conflict_engine_exception",
    "reason" : "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
    "index_uuid" : "iGtCA6A_TyeQeHrMM9_c7A",
    "shard" : "0",
    "index" : "pigg_test"
  },
  "status" : 409
}

5. 删除文档,_seq_no还是会+1

DELETE pigg_test/_doc/1

删除后_seq_no变成了3,如果再次创建id=1的文档时,_seq_no还是会+1,变成4

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

6. seq_no递增属于整个index,而不是单个文档

这个时候再创建一个id=2的文档

PUT /pigg_test/_doc/2
{
  "name": "珣爷",
  "age": 28,
  "interest": ["music", "sleep"],
  "about": "I am a tester"
}

1.返回中_seq_no=4,这个是id=1的seq_no上再加一的,所以说_seq_no递增是属于整个索引。
2.但是每个文档依旧有自己的seq_no值,更新一个文档时,还是用该文档的seq_no控制并发。
3.当index中任何文档修改或新增,seq_no都会+1。
4.例如id=1的文档创建后seq_no=1,
5.那么id=2的文档创建后,seq_no=2,
6.再然后id=1的文档修改后,seq_no=3
7.再对id=2的文档修改,要并发控制,if_seq_no得=2

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}

原文地址:
https://blog.csdn.net/winterking3/article/details/108095851

;