[ElasticSearch]乐观并发控制技术
ElasticSearch是分布式的搜索引擎。在数据更新的时候,新的文档必须复制到其他集群中的其他节点。这一操作是异步和并发的,也就是说这些请求是被并行(几乎同时)发送出去的,由于中间存在网络的不确定性,可能会导致接收到的数据并非按照之前发送的顺序接收的,也就是可能会乱序到达。
ElasticSearch在应对这种情况的时候才去了乐观的并发控制,所谓的乐观并发控制就是基于版本号的并发控制技术。
一、内部并发控制
内部并发控制是采用_version字段来进行的,ElasticSearch会为每个文档添加一个_version的字段来标识文档的版本,更新操作会增加_version的值。
如果旧版本在新版本之后到达目标节点,目标节点将会拒绝旧版本的更新操作;即当前版本号是否要小于新指定的要更新的文档版本号,如果是,那么拒绝更新。
注意:版本号是递增的,拒绝更新操作ElasticSearch会返回409 Conflict HTTP Response
所有的文档的更新或删除API,都可以接受version参数
如何处理版本冲突:
获取新的version并重试更新 提示客户端版本已经更新
二、外部并发控制
外部并发控制方式是指使用数据库作为主要的数据存储,使用ElasticSearch做数据检索,数据库的操作就必须同步到ElasticSearch,如果多个进程负责数据的同步,也会遇到并发问题。
如果数据库中已经有了一个版本号(或时间戳,不过不建议使用时间戳做版本号),那么就可以使用version_type=external
来指定版本查询。版本号必须是大于0且小于9.2E+18的整数,对应于java中的long类型正值。
外部版本号的处理是检查当前文档的_version是否小于指定的更新新文档的版本号,如果是那么才会更新成功,同时也会存储外部版本号。
三、以上两者区别
外部版本控制是脱离es的内部版本控制,内部version字段仅记录版本信息,并且控制版本递增即可(可能并不连续);内部版本号是递增且连续的。 外部版本控制实际版本号的生成其实是由外部系统来生成的。 外部版本号比较的是当前文档版本是否小于更新指定的文档版本号,如果是就可以更新;内部版本号是判断当前版本号是否为更新文档指定的版本号。
注意:外部版本号必须是递增的
另外:乐观的并发控制会用在很多的场景中,比如数据库mysql的 innodb引擎中的MVCC,数据控中间件中的逻辑时钟version字段,以及现在的es的版本并发控制等等
- END -



