• ElasticSearch之并发操作处理


    写在前面

    在这里插入图片描述

    并发控制,一般有两种方案,悲观锁和乐观锁,其中悲观锁是默认每次更新操作肯定会冲突,所以每次操作都要先获取锁,操作完毕再释放锁,适用于写比较多的场景。而乐观锁是默认每次更新操作都不会冲突,所以在更新前和更新后都不需要获取锁和释放锁的操作,所以效率更高,适合于读多写少的场景中。

    在es中采用的是乐观锁机制,这也很好理解,因为es的定位是一个搜索引擎,所以一般是应用于读多写少的场景中。

    1:es的乐观锁机制

    有如下3中方式:

    1:每次更新文档的version都会+1
        这种方式已废弃
    2:内部版本号控制,通过if_seq_no+if_primary_term
    3:外部版本号控制,version+verion_type=exeternal,其中verison由外部数据源指定,如数据从MySQL同步
    
    • 1
    • 2
    • 3
    • 4

    如果是数据在es中维护更新则采用2,内部版本号控制方案,如果是数据来自于外部数据源的同步,则采用3,外部版本号控制。

    1.1:内部版本号控制

    • 插入数据
    DELETE products
    
    PUT products/_doc/1
    {
      "title": "iphone",
      "count": 100
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意返回的_seq_no和_primary_term需要记住,在做并发更新控制时需要用到:
    在这里插入图片描述

    • 指定if_seq_no和if_primary_term更新一次
    PUT products/_doc/1?if_seq_no=0&if_primary_term=1
    {
      "title": "iphone",
      "count": 100
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    假定此时有一个并发修改也指定了?if_seq_no=0&if_primary_term=1则会因为乐观锁检测而失败:
    在这里插入图片描述

    1.2:外部版本号控制

    外部版本号通过version=${外部版本号}&version_type=external完成,如下:

    DELETE products
    
    PUT products/_doc/1
    {
      "title": "iphone",
      "count": 100
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    假定外部版本号时10000:

    
    PUT products/_doc/1?version=10000&version_type=external
    {
      "title": "iphone",
      "count": 100
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中version由外部数据源指定,此时如果有并发修改的话,同样会被乐观锁机制检测到异常:
    在这里插入图片描述

    写在后面

    参考文章列表

  • 相关阅读:
    mongodb
    【springboot】你了解@Autowired 和 @Resource吗?@Autowired 和 @Resource深入分析
    Redis的RDB与AOF持久化机制
    【老生谈算法】matlab实现连续时间系统的频域分析与仿真——频域分析
    【面试】你有使用过链路追踪技术吗?
    Shell入门2
    设计模式-05-代理模式
    如何通过Express和React处理SSE
    如何做 React 性能优化?
    kafka集群配置
  • 原文地址:https://blog.csdn.net/wang0907/article/details/136532776