_version 乐观锁并发控制
和 cas
类似,es 也通过类似 offset
的版本号 version
,进行乐观锁并发控制,以解决并发更新带来的冲突。
在进行更新操作的时候:
- 首先从 es 中获取数据和数据的版本号
version
- 更新完成,将更新后的数据和版本号包装成更新请求发送给 es
- 如果内置的
version
与请求提供的版本号相同,则 es 将数据写回,然后将version + 1
- 否则更新失败,返回错误
es 允许不使用内置版本号进行并发控制操作:
- 内置的
_version
,只有当提供的version
与 es 中的_version
完全一致才可以进行更新; - 外部的
_version
,只有提供的version
比 es 中的_version
大的时候才可以更新。
Replica Shard 数据同步并发控制:
当 primary shard
收到新的数据时,需要对 replica shard
进行数据同步。如果同一个 document
进行了多次修改,shard
同步的请求是无序的,不能保证 "先到先出"。数据同步的并发请求特别多,如果更新时出现了错误,那么就要重复进行同步,可能一直都无法成功同步,这可能会造成严重的后果。
为解决此类问题,同样的,es 基于内置的 _version
对 shard
进行数据同步。
由于数据同步并不需要对数据进行计算,也就是说数据的同步是上下文无关的,所以只要保证最后一次的同步能够完成即可。
只要提供的版本号较当前 _version
大,就允许更新;
如果提供的版本号比内置 _version
小,那么说明数据是过期的,但也不需要重复请求。
这样最终的结果也是正确的。