(10)ElasticSearch 版本控制

  ElasticSearch是多用户操作的 ,需要保证数据的一致性,它用乐观锁保证数据的一致性,用户每次操作一次文档,它的版本号就会自动加1,用户对文档操作时,不需要对文档加锁、解锁,只需要指定要操作的版本。当版本号一致时,ElasticSearch会允许该操作顺利执行,而当版本号存在冲突时,ElasticSearch会提示冲突并抛出异常。ElasticSearch的版本号的取值范围是1到2^63-1。

  1、内部版本控制

  使用的是_version,下面是个简单例子:

POST /lib2/books/_bulk
{"index":{"_id":1}}
{"title":"Html5","price":45}

  显示版本号是3,"_version": 3,结果如下:

{
  "took": 19,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "lib2",
        "_type": "books",
        "_id": "1",
        "_version": 3,
        "result": "updated",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 7,
        "_primary_term": 1,
        "status": 200
      }
    }
  ]
}

  现在将价格修改为50,执行下面的语句,从结果中看到"_version":4,版本号增加了1,

PUT /lib2/books/1?version=3
{
  "title":"Html5",
  "price":50
}
{
  "_index": "lib2",
  "_type": "books",
  "_id": "1",
  "_version": 4,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 8,
  "_primary_term": 1
}

  现在版本号是4,如果执行版本号为5的操作,会报冲突,如下所示:

PUT /lib2/books/1?version=5
{
  "title":"Html5",
  "price":50
}
{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[books][1]: version conflict, current version [4] is different than the one provided [5]",
        "index_uuid": "yL8koqQqQVqf3uoyvTcBHA",
        "shard": "3",
        "index": "lib2"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[books][1]: version conflict, current version [4] is different than the one provided [5]",
    "index_uuid": "yL8koqQqQVqf3uoyvTcBHA",
    "shard": "3",
    "index": "lib2"
  },
  "status": 409
}

  2、外部版本控制

  所谓外部版本号指的是ElasticSearch与关系型数据库一块使用时,关系型数据实现锁机制中的版本号。ElasticSearch在处理外部版本号时与对内部版本号的处理有些不同。它不再检查_version是否与请求中指定的数值相同,而是检查当前的_version是否比指定的数值小。如果请求成功,那么外部的版本号就会被存储到文档中的_version中。为了保持_version与外部版本控制的数据一致,使用version_type=external。

  参考下面的例子,现在版本号是4,执行为版本号为5的操作,可以成功,版本号变为5

PUT /lib2/books/1?version=5&version_type=external
{
  "title":"Html5",
  "price":50
}
{
  "_index": "lib2",
  "_type": "books",
  "_id": "1",
  "_version": 5,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 9,
  "_primary_term": 1
}

  现在版本号是5,执行版本号是5的操作会报冲突,执行的只能大于当前的。如下:

PUT /lib2/books/1?version=5&version_type=external
{
  "title":"Html5",
  "price":50
}
{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[books][1]: version conflict, current version [5] is higher or equal to the one provided [5]",
        "index_uuid": "yL8koqQqQVqf3uoyvTcBHA",
        "shard": "3",
        "index": "lib2"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[books][1]: version conflict, current version [5] is higher or equal to the one provided [5]",
    "index_uuid": "yL8koqQqQVqf3uoyvTcBHA",
    "shard": "3",
    "index": "lib2"
  },
  "status": 409
}

  现在版本号是5,执行一次版本号是12的,执行完后,版本号变为了12,如下:

PUT /lib2/books/1?version=12&version_type=external
{
  "title":"Html5",
  "price":50
}
{
  "_index": "lib2",
  "_type": "books",
  "_id": "1",
  "_version": 12,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 10,
  "_primary_term": 1
}


  

猜你喜欢

转载自www.cnblogs.com/javasl/p/11405365.html