ElasticSearch | 处理并发读写操作

并发控制的必要性

ElasticSearch | 处理并发读写操作_第1张图片
并发案例.png
  • 两个 Web 程序同时更新某个文档,如果缺乏有效的并发,会导致更改的数据丢失;
悲观并发控制
  • 假定有同时写共享变量的可能,会对资源加锁,例如数据库行锁;
乐观并发控制
  • 假定冲突是不会发生的,不会阻止正在尝试的操作;
  • 如果数据在读写中被更改,读写将失败;
  • 应用程序决定如何解决冲突,例如重试机制,使用新的数据,或者将错误报告给用户;
  • ES 采用的是乐观并发控制;

ElasticSearch 的乐观并发控制

ElasticSearch 中的文档是不可变更的,如果更新一个文档,会将旧文档标记为删除,同时增加一个全新的文档,并且文档的 version 会加 1;

内部版本控制
  • 使用 if_seq_no + if_primary_term 做并发控制
外部版本控制
  • 使用其他数据库作为主要数据存储

内部版本控制 | 举个栗子

数据准备
  • 写入文档,会返回 _seq_no 和 _primary_term;
DELETE products
PUT products

PUT products/_doc/1
{
  "title":"iphone",
  "count":100
}
更新操作
  • 根据文档当前的 _seq_no 和 _primary_term 去更新文档,更新成功,同时文档的 _seq_no 和 _primary_term 会增加;
  • 如果此时有别的请求用增加前的 _seq_no 和 _primary_term 尝试更新文档,会失败;当更新失败的时候,就需要程序去处理更新失败的问题;
  • 通过这种机制,保证并发写的正确性;
PUT products/_doc/1?if_seq_no=1&if_primary_term=1
{
  "title":"iphone",
  "count":100
}

外部版本控制 | 举个栗子

比如应用的数据主要是在 MySQL 中存储,ElasticSearch 只是做一个数据的同步用以支持搜索。

使用 version + version_type 控制并发写
  • MySQL 中的记录也有 version 字段;
  • 写入成功,并且文档的 _version 变为 30000;
  • 如果再次更新,带的 version 还是 30000,那么更新会失败,带的 version 值更大的话,更新会成功;
PUT products/_doc/1?version=30000&version_type=external
{
  "title":"iphone",
  "count":100
}

你可能感兴趣的:(ElasticSearch | 处理并发读写操作)