Elasticsearch:处理并发冲突

问:乐观并发控制-版本号形式的锁,在更新数据的时候是否会阻塞?

答:不会阻塞。类似于 CAS算法 中ABA问题的解决方案。

业务场景:想象一下我们使用Elasticsearch存储大量在线商店的库存信息。每当销售一个商品,Elasticsearch中的库存就要减一。想象两个同时运行的web进程,两者同时处理一件商品的订单时,并发情况下会造成“幻读”,并且变化越频繁,越容易丢失我们的修改:

                            

ElasticSearch内部如何基于_version进行乐观锁并发控制?

1._version元数据

1.1 向指定index存入数据:

1

2

3

4

5

6

7

8

PUT student/student/5

{

  "id":4,

  "name":"流川枫",

  "age":18,

  "address":"东京大学",

  "gender":"男"

}

1.2 返回信息:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

{

  "_index" "student",

  "_type" "student",

  "_id" "5",

  "_version" 1,

  "result" "created",

  "_shards" : {

    "total" 2,

    "successful" 1,

    "failed" 0

  },

  "_seq_no" 8,

  "_primary_term" 3

}

     第一次创建一个document的时候 ,它内部的版本号就是1;此后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1;

1.3 多次修改后的查询语句及结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

# query

GET student/_search

{

  "query": {

    "match": {

      "id"5

    }

  }

  "version"true

}

# result

{

  "took" 1,

  "timed_out" false,

  "_shards" : {

    "total" 3,

    "successful" 3,

    "skipped" 0,

    "failed" 0

  },

  "hits" : {

    "total" 1,

    "max_score" 1.0,

    "hits" : [

      {

        "_index" "student",

        "_type" "student",

        "_id" "5",

        "_version" 9,

        "_score" 1.0,

        "_source" : {

          "id" 5,

          "name" "流川枫",

          "age" 18,

          "address" "东京大学",

          "gender" "男"

        }

      }

    ]

  }

}

1.4 执行删除当前document的语句已返回结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

DELETE student/student/5

# 删除document = 5 的数据

# 返回结果

{

  "_index" "student",

  "_type" "student",

  "_id" "5",

  "_version" 11,

  "result" "deleted",

  "_shards" : {

    "total" 2,

    "successful" 1,

    "failed" 0

  },

  "_seq_no" 18,

  "_primary_term" 3

}

        由上述返回结果可以发现,在执行 DELETE student/student/5 之后,返回的处理结果中存在 : "result" : "deleted" (证明执行的是删除操作) 、 "_version" : 11 (证明当前document已经执行了11次)。此时可以从侧面证明,ElasticSearch在删除某一条document数据时,不是立即物理删除掉的。因为它的一些版本号等信息还是保留着的。先删除一条document,再重新创建这条document,其实会在delete version基础之上,再把version号加1.

elasticsearch内部的多线程异步并发修改时是基于自己的_version版本号进行乐观锁并发控制的。

2.基于external version进行乐观锁并发控制

        es提供了一个feature,就是说,你可以不用它提供的内部_version版本号来进行并发控制,可以基于你自己维护的一个版本号来进行并发控制。举个列子,假如你的数据在mysql里也有一份,然后你的应用系统本身就维护了一个版本号,不管是什么自己生成的还是程序控制的。这个时候,你进行乐观锁并发控制的时候,可能并不是想要用es内部的_version来进行控制,而是用你自己维护的那个version来进行控制。

1

2

......?version=1

......?version=1&version_type=external

       version_type=external唯一的区别在于:_version,只有当你提供的version与es中的_version一模一样的时候,才可以进行修改,只要不一样,就报错;当version_type=external的时候,只有当你提供的version比es中的_version大的时候,才能完成修改。

1

2

3

es,_version=1,?version=1 -- 更新成功

es,_version=1,?version>1&version_type=external -- 更新成功

?version=2&version_type=external -- 更新成功

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值