热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ElasticSearchupdateapi和update_by_query哪家强

ElasticSearchupdateapi和update_by_query哪家强,Go语言社区,Golang程序员人脉社

很久没有怎么随记笔记了,今天这里是为了纠正一个一直以来我们使用es的一个误区,这个误区很大的可能你会就范。很多童靴会把update_by_query拿mysql的语法特性来用,那你就大错特错了,这里有必要温习下我之前的一篇update_by_query,理论上讲es的准实时的仅限于search,而get id则是实时的。

实践往往是检验真理的唯一标准,看下面演示吧


http://xxx:9200/mytest_user/_settings
{
    "index" : {
        "refresh_interval" : -1
    }
}

http://xxx:9200/mytest_user/_doc/2
{
	"product_type": "test",
  	"product_code": "324049",
	"shop_code": "9N72"
}

http://xxx:9200/mytest_user/_doc/2/_update
{ "doc" : {
        "name" : "new_name"
    }
}
http://xxx:9200/mytest_user/_doc/2/_update
{ "doc" : {
        "name" : "alex",
        "age" : 20
    }
}
...

http://xxx:9200/mytest_user/_update_by_query?cOnflicts=proceed
{
  
  "query" : {
    "term" : { "product_code": "324049" }
  },
   "script": {
    "source": "ctx._source.en_product_name='cn';ctx._source.plu_code='00';"
  }
}

http://xxx:9200/mytest_user/_doc/2

没错_update_by_query使用了search,顾没有任何反应。而update api借助get API的实时性做到了(即先根据文档ID做一次GET,然后拿最新文档修改后写回去),而get API为此有个参数可以控制的是为非实时(http://xxx:9200/mytest_user/_doc/4?realtime=false)。

realtime

官方介绍,默认情况下,get API是实时的,并且不受索引刷新率的影响(当数据在搜索中变为可见时)。如果文档已更新但尚未刷新,则get API将发出刷新调用以使文档可见。这还会使上次刷新后的其他文档可见。为了禁用realtime GET,可以将realtime参数设置为false。

update API的文档和源码都没有提供一个“禁用”实时性的参数。update对GET的调用,传入的realtime是写死为true的。

为何get API会要求实时?

update允许对文档做部分字段更新。如果有2个请求分别更新了不同的字段, 可能先更新的数据只在writter buffer里,searcher里看不到,那后面的更新还是在老版本文档上做的,造成部分更新丢失。 

上面的结论我们借助cat的监控可以看到:http://xxx:9200/_cat/segments/mytest_user?v

如果realtime设置为false,就从searcher里面拿,而searcher只能访问refresh过的数据。刚写入的数据存在于index writter buffer里,暂时无法搜索到,所以这种方式拿到的数据是准实时的。

在5.x版本以上,实时则能够访问到index writter buffer里的数据,并且还执行了强制刷新(并非refresh_interval),生成了新的segment file。如果短时间反复大量更新相同doc id的操作,会因为过于频繁的refresh短时间生成很多小segment,继而不断做短合产生性能损耗。官方认为,在提升大多数应用场景性能情况下,对于这种较少见的场景下的性能损失是值得的,应该在应用层面解决。

注:update方法更新文档,如果关闭了Upsert,意味着如果更新的文档id如果不存在,会抛出doc missing异常,大量抛出和捕获doc missing异常开销很高。

在2.4版本中,没有采用refresh的方式让数据实时,而是直接访问的translog来保证GET的实时性。官方在这个变更里 https://github.com/elastic/elasticsearch/pull/20102   将其更新方式改为了refresh。理由是之前ES里有很多地方用translog维护数据的位置,使得很多操作变得很慢,去掉对translog的依赖可以提高性能。

代码验证环节

代码实现中确实有realtime参数和 refresh("realtime_get"); 的函数调用

//源自core/src/main/java/org/elasticsearch/index/engine/InternalEngine.java
public GetResult get(Get get, Function searcherFactory, LongConsumer onRefresh) throws EngineException {
        assert Objects.equals(get.uid().field(), uidField) : get.uid().field();
        try (ReleasableLock lock = readLock.acquire()) {
            ensureOpen();
            if (get.realtime()) {
                VersionValue versiOnValue= versionMap.getUnderLock(get.uid());
                if (versionValue != null) {
                    if (versionValue.isDelete()) {
                        return GetResult.NOT_EXISTS;
                    }
                    if (get.versionType().isVersionConflictForReads(versionValue.getVersion(), get.version())) {
                        throw new VersionConflictEngineException(shardId, get.type(), get.id(),
                            get.versionType().explainConflictForReads(versionValue.getVersion(), get.version()));
                    }
                    long time = System.nanoTime();
                    refresh("realtime_get");
                    onRefresh.accept(System.nanoTime() - time);
                }
            }

            // no version, get the version from the index, we know that we refresh on flush
            return getFromSearcher(get, searcherFactory);
        }

现在足以可见如果对es的更新需求特别多,首先需要考虑借助get API(依赖 _id),否则使用update_by_query还是你手写的类似语义(先search,再update)都不得不接受更新丢失的问题。


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
author-avatar
背对夕阳宝宝_732
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有