美文网首页
21.es如何处理冲突和添加外部版本号

21.es如何处理冲突和添加外部版本号

作者: 不怕天黑_0819 | 来源:发表于2020-08-11 09:26 被阅读0次

本文集主要是总结自己在项目中使用ES 的经验教训,包括各种实战和调优。

在数据库中,有两种通用的方法确保在并发更新时修改不丢失:

悲观并发控制(Pessimistic concurrency control)

这在关系型数据库中被广泛的使用,假设冲突的更改经常发生,为了解决冲突我们把访问区块化。典型的例子是在读一行数据前锁定这行,然后确保只有加锁的那个线程可以修改这行数据。

乐观并发控制(Optimistic concurrency control):

被Elasticsearch使用,假设冲突不经常发生,也不区块化访问,然而,如果在读写过程中数据发生了变化,更新操作将失败。这时候由程序决定在失败后如何解决冲突。实际情况中,可以重新尝试更新,刷新数据(重新读取)或者直接反馈给用户。

冲突处理:采用乐观并发控制

Elasticsearch 是分布式的。当文档创建、更新或删除时, 新版本的文档必须复制到集群中的其他节点。Elasticsearch 也是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时也许 顺序是乱的 。 Elasticsearch 需要一种方法确保文档的旧版本不会覆盖新的版本。(通过_verison号来确保变更以正确的顺序执行)我们通过指定想要修改文档的 version 号来达到这个目的。 如果该版本不是当前版本号,我们的请求将会失败。
示例如下:

PUT /website/blog/1/_create   先创建一个文档
GET /website/blog/1       检索文档,看是否存在
PUT /website/blog/1?version=1        

重建文档的索引来保存修改,指定 version 为我们的修改会被应用的版本(索引中的文档只有现在的 _version 为 1 时,本次更新才能成功,否则返回409 Conflict HTTP相应码)
所有文档的更新或删除 API,都可以接受 version 参数,这允许你在代码中使用乐观的并发控制,这是一种明智的做法。

通过外部系统使用版本控制

一种常见的结构是使用一些其他的数据库做为主数据库,然后使用Elasticsearch搜索数据,这意味着所有主数据库发生变化,就要将其拷贝到Elasticsearch中。如果有多个进程负责这些数据的同步,就会遇到上面提到的并发问题。
如果主数据库有版本字段或一些类似于timestamp等可以用于版本控制的字段是你就可以在Elasticsearch的查询字符串后面添加version_type=external来使用这些版本号。版本号必须是整数,大于零小于9.2e+18—Java中的正的long。
外部版本号与之前说的内部版本号在处理的时候有些不同。它不再检查_version是否与请求中指定的一致,而是检查是否小于指定的版本。如果请求成功,外部版本号就会被存储到_version中。
外部版本号不仅在索引和删除请求中指定,也可以在创建(create)新文档中指定。
例如,创建一个包含外部版本号5的新博客,我们可以这样做:

PUT /website/blog/2?version=5&version_type=external
{
  "title": "My first external blog entry",
  "text":  "Starting to get the hang of this..."
}

在响应中,我们能看到当前的_version号码是5:

{
  "_index":   "website",
  "_type":    "blog",
  "_id":      "2",
  "_version": 5,
  "created":  true
}

现在我们更新这个文档,指定一个新version号码为10:

PUT /website/blog/2?version=10&version_type=external
{
  "title": "My first external blog entry",
  "text":  "This is a piece of cake..."
}

请求成功的设置了当前_version为10:

{
  "_index":   "website",
  "_type":    "blog",
  "_id":      "2",
  "_version": 10,
  "created":  false
}

如果你重新运行这个请求,就会返回一个像之前一样的冲突错误,因为指定的外部版本号不大于当前在Elasticsearch中的版本。

相关文章

  • 21.es如何处理冲突和添加外部版本号

    本文集主要是总结自己在项目中使用ES 的经验教训,包括各种实战和调优。 在数据库中,有两种通用的方法确保在并发更新...

  • Android 事件冲突处理

    概述 本文主要分享Android常见的事件冲突处理,处理方式有两种: 外部拦截:父容器处理冲突 内部拦截:子控件处...

  • 《家庭关系工作坊》第二天

    今天的课程经营婚姻从拥有处理冲突的能力和如何处理冲突两点分析。 一、处理冲突的能力 1.夫妻双方原生家庭的生活习惯...

  • 婚姻致命伤之不知如何有效地处理冲突

    5.不知如何有效地处理冲突 我们自小就被教导谦逊忍让,却没学过如何去处理冲突,导致长大后遇到冲突,不是不断地忍让,...

  • 家庭教育分享

    社会能力就是孩子解决冲突和与人相处的能力,如何与同伴友好相处,如何通过沟通协商来处理同伴间的争端和冲突,是儿童成长...

  • 冲突-心情糟透了

    冲突在所难免,在冲突学习如何更有技巧的处理冲突; 我的沟通方式有问题?极其容易被自己的情绪所困扰和带跑偏 和人发生...

  • openmnt如何添加外部特征

    在做机器翻译任务时,如果除了基本的双语语料,还想添加一些额外的特征,如单词的词性等,具体代码需要怎么做?openm...

  • Android View 事件体系笔记 (三):View滑动冲突

    一、View 滑动冲突背景 1.1 View 滑动冲突常见场景 场景1 —— 外部和内部横竖滑动交错冲突 场景2 ...

  • View滑动冲突

    如何解决滑动冲突,这里有两种方法 外部拦截法 简单来说:点击事件都先经过父容器的拦截处理,如果父容器需要此事件就拦...

  • Android View的事件体系(五) View的滑动冲突

    滑动冲突时如何产生的呢?在界面中只要内外两层同时可以滑动,这个时候就会产生滑动冲突. 常见的滑动冲突场景 1 外部...

网友评论

      本文标题:21.es如何处理冲突和添加外部版本号

      本文链接:https://www.haomeiwen.com/subject/hoxorktx.html