大数据-183 Elasticsearch 并发冲突与乐观锁
1. 并发冲突场景
以电商库存扣减为例:
- 线程 A 读取库存:count = 10
- 线程 B 读取库存:count = 10
- 线程 A 扣减:count = 9,写入
- 线程 B 扣减:count = 9,写入
结果:库存本应 8,实际 9,写覆盖导致数据错误。
2. 乐观锁 vs 悲观锁
2.1 悲观锁
- 每次拿数据加锁
- 并发能力低
2.2 乐观锁
- 文档含 version 字段
- 每次修改累加版本号
- 写入时比对版本号
3. ES 乐观锁实现
使用 _seq_no 和 _primary_term 做条件写入:
PUT /index/_doc/1?if_seq_no=5&if_primary_term=1
{
"field": "value"
}
- 成功:正常更新
- 冲突:返回 HTTP 409
version_conflict_engine_exception
4. 分布式一致性
ES 5.0 前
?consistency=quorum # 必须有半数以上副本响应
?consistency=one # 必须有主分片响应
?consistency=all # 必须所有副本响应
ES 5.0 后
?wait_for_active_shards=2 # 必须有 2 个活跃副本
5. 总结
- 并发场景用乐观锁
- ES 通过
if_seq_no+if_primary_term实现条件写入 - 分布式一致性用
wait_for_active_shards控制