图解Elasticsearch内部如何基于_version进行乐观锁并发控制

_version元数据:第一次创建一个document的时候,它的_version内部版本号就是1;以后每次对这个document执行修改或者删除的时候,都会对这个_version版本号自动加1,哪怕是删除操作,也会对这条数据的版本号加1.

创建一个document:

PUT test_index/test_type/1
{
  "test_field":"test1"
}

运行结果:

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

测试删除:

DELETE test_index/test_type/1

运行结果:

{
  "_index": "test_index",
  "_type": "test_type",
  "_id": "1",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 17,
  "_primary_term": 1
}

测试修改:

PUT test_index/test_type/1
{
  "test_field":"test123"
}

运行结果

{
  "_index": "test_index",
  "_type": "test_type",
  "_id": "1",
  "_version": 3,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 18,
  "_primary_term": 1
}

我们发现,在删除一个document之后,可以一个从一个侧面证明,它不是立刻物流删除的,因为它的版本号等信息还是保留着的,先删除一条document,再重新创建document,其实会在delete version基础之上,再把version加1

在这里插入图片描述
首先我们创建一条document field=test1,现在有2个线程,线程A先修改数据,把field修改成test2,线程B后修改,将数据修改成test3,这两条线程现在的version都是1,但是A线程虽然是先操作的,但是并不一定先对数据就行修改,因为在es后台shard同步replica是基于多线程异步请求的,也就是说,多个线程修改请求都是乱序的,没有顺序的,所以可能会出现B线程先到,A线程反而后到。
(1)第一种情况:如果B线程(后修改的)先到,携带的版本号是1,对数据进行修改时,把field修改成test3,此时version版本变成2,而这个时候A线程(先修改的)也到了,此时携带的版本号还是1,对数据就行修改时,此时就会比较version版本号,如果相等,就可以正常修改成功。如果version版本不同,说明版本已经被其他人修改过了,然而发现线程A就先就行修改的,这个时候说明这个数据是旧数据了,es就会把这条数据扔掉。此时最终结果就是一个正确的状态,field=test3。
(2)第二种情况:如果A线程(先修改的)先到了,携带的版本号是1,对数据进行修改,此时执行写操作的时候,会判断当前的版本号跟es的版本号,此时es的版本号1,显然版本号一样,写操作成功,此时field被修改成test2,此时es的版本号变成2,而这个时候线程B到了,携带的版本号还是1,对数据进行修改,同样先判定版本号,发现版本号不同,说明这条数据已经被人修改过了,此时,会重新读取es的数据版本,此时B线程也变成2,再次执行上述操作,发现版本号一样,执行写操作,此时最终结果就是一个正确的状态,数据修改成test3

总体而言:es不会让旧的数据覆盖新数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值