余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Elasticsearch搜索调优权威指南 (2/3)(elasticsearch 搜索建议)

xiyangw 2022-11-25 11:48 85 浏览 0 评论

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/AAkVdzmkgdBisuQZldsnvg

英文原文:https://qbox.io/blog/elasticsearch-search-tuning-part-2

作者:Adam Vanderbush

译者:杨振涛

目录

  1. 预索引数据
  2. 映射
  3. 避免使用脚本
  4. 强制合并只读索引

Elasticsearch搜索调优权威指南,是QBOX在其博客上发布的系列文章之一,本文是该系列的第二篇,主要介绍了索引预处理、mapping建立、避免脚本的使用、索引段合并等搜索性能相关的调优方法。

本文是Elasticsearch搜索调优系列文章3篇中的第2篇,第1篇参考这里(点击)。本系列教程旨在更进一步讨论针对Elasticsearch 5.0及以上版本的搜索调优技术、策略及建议。

1.预索引数据

为了优化数据的索引方式,应当在查询中预置一些模式。比如,如果所有文档都有一个叫 price 的价格字段,并且大部分查询在一个固定范围列表上执行 range 聚合,那么就可以通过预索引范围到索引中并使用一个 terms 聚合,来加速该聚合。

比如有如下文档:

curl -XPUT 'ES_HOST:ES_PORT/index/type/1
?pretty' -H 'Content-Type: application/json' -d '{
 "designation": "bowl",
 "price": 13
}'

以及如下搜索请求:

curl -XGET 'ES_HOST:ES_PORT/index/_search
?pretty' -H 'Content-Type: application/json' -d '{
 "aggs": {
 "price_ranges": {
 "range": {
 "field": "price",
 "ranges": [
 { "to": 10 },
 { "from": 10, "to": 100 },
 { "from": 100 }
 ]
 }
 }
 }
}'

然后就可以在索引阶段增加一个 price_range 字段,该字段应该映射为一个关键字:

curl -XPUT 'ES_HOST:ES_PORT/index
?pretty' -H 'Content-Type: application/json' -d '{
 "mappings": {
 "type": {
 "properties": {
 "price_range": {
 "type": "keyword"
 }
 }
 }
 }
}'
curl -XPUT 'ES_HOST:ES_PORT/index/type/1
?pretty' -H 'Content-Type: application/json' -d '{
 "designation": "bowl",
 "price": 13,
 "price_range": "10-100"
}'

接下来搜索请求就能聚合这个新的字段,而不是在 price 字段上执行一个范围聚合。

curl -XGET 'ES_HOST:ES_PORT/index/_search
?pretty' -H 'Content-Type: application/json' -d '{
 "aggs": {
 "price_ranges": {
 "terms": {
 "field": "price_range"
 }
 }
 }
}'

2.映射

事实上,一些数值型的数据,并不意味着总是要被映射为一个数值型字段。典型的,那些存储为诸如 ISBN 之类的标识符,或者任何标识另一个数据库中记录的数字的字段,可能映射为关键字比映射为一个 integer long 类型更好。

关键字类型用于索引结构化内容,比如 email 地址、主机名称、状态码、邮政编码或标签。

典型地用于过滤(比如查找所有已发布的博客文章)、排序以及聚合。关键字字段只可通过其精确值搜索得到。

如果需要索引全文内容比如 email 内容或产品描述,可能就要使用一个文本字段。

下面是一个关键字字段映射的示例:

curl -XPUT 'ES_HOST:ES_PORT/my_index
?pretty' -H 'Content-Type: application/json' -d '{
 "mappings": {
 "my_type": {
 "properties": {
 "tags": {
 "type": "keyword"
 }
 }
 }
 }
}'

2.x 版本导入的索引是不支持关键字的;相反,它们会试图把 keyword 类型降级为 string 类型。这支持合并新的映射和旧的映射。长期存在的索引,必须在升级到6.x 版本前重建,但是映射降级提供了按自己的计划实施重建的机会。

3.避免使用脚本

一般来说要尽量避免使用脚本;如果必须要使用,优先选择 Painless 和表达式引擎。

Painless 是一门简单安全的脚本语言,专门为在 Elasticsearch 中使用而设计,是 Elasticsearch 的默认脚本语言,可安全地用于内联和存储脚本。关于 Painless 语法和语言特性的更详细描述,请参考 Painless 语言规范。

请参考 “ Painless Scripting in Elasticsearch ” 更深入地了解 Painless 脚本语言指南。

  • Lucene 表达式语言

Lucene 表达式会把一个 javascript 表达式编译为字节码,设计用于高性能自定义评级和排序函数,并支持 inline 和默认的存储脚本。

  • 性能

表达式相对于自定义 Lucene 代码而言有着更好的性能表现;其性能相对其他脚本引擎有更低的单文档成本:表达式更加“领先”。

这就允许非常快的执行,尤其是比自己写的本地脚本快很多。

  • 语法

表达式支持一个 javascript 语法子集:一个单独的表达式。参见表达式模块的文档,了解支持的操作符和函数。

表达式脚本中可访问的变量有:

  • 文档字段,比如doc['myfield'].value
  • 字段所支持的变量和方法,比如doc['myfield'].empty
  • 传递到脚本里的参数,比如mymodifier
  • 当前文档得分,_score(仅在 script_score中使用时有效)

表达式脚本可以用于script_score、script_fields、排序脚本以及数值型聚合脚本,只要简单地设置参数到表达式中即可。

4.强制合并只读索引

只读索引在合并为单一的段后将会非常受益。典型的情况是基于时间的索引:只有当前时间窗的索引会成为新文档,同时旧索引成为只读。

强制合并 API 支持通过 API 强制合并一个或更多的索引。合并与每个分片中 Lucene索引的段数量有关。强制合并操作支持通过合并来减少段数量。

该调用在合并完成之前将会处于阻塞状态。如果 http 连接断掉,请求将在后台继续,在前一个强制合并完成之前,所有新请求将会阻塞。

curl _XPOST 'ES_HOST:ES_POST/twitter/_forcemer
ge?pretty'

强制合并 API 接受下列请求参数:

  • max_num_segments - 待合并的段数量。要完全合并索引,可设置为 1 。默认会简单检查一个合并是否需要执行,如果是,就会执行。
  • only_expunge_deletes -合并流程是否仅仅擦除包含删除的段。在 Lucene 中,一个文档并不会从一个段直接删除,只是标记为删除。在一个段合并的过程中,一个新的段可能会被创建,这个新的段并不包含那些删除。这个标记参数支持只合并有删除的段,且默认为false。注意,这并不会重写阈值 index.merge.policy.expunge_deletes_allowed。
  • flush - 强制合并后是否执行 flush,默认为 true

更多内容敬请关注 vivo 互联网技术 微信公众号

注:转载文章请先与微信号:labs2020 联系。K码农提供了很多不同领域技术,包含人工智能,android,ios ,前端,后端,大数据,云计算,区块链,物联网等大量的技术:http://kmanong.top

相关推荐

排序算法--归并排序_归并排序例题讲解

原理如图所示(先分割再合并):归并排序代码工作原理:1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列2、设定两个指针,最初位置分别为两个已经排序序列的起始位置3、比较两个指针所...

八大排序算法-归并排序_归并排序 算法

算法思想归并排序分为三个步骤:1.分解:将数列分解成n个子数列。(如果是将数列分成2个子数列则为2路归并)2.治理:对每个子数列进行排序操作3.合并:将两个排好序的子数列进行合并生成新的数列算法实现P...

高级排序之归并排序、希尔排序_希尔排序和归并排序区别

前言继上次排序算法简单排序算法之冒泡、插入和选择排序-Java实现版后,本文学习高级排序算法——归并排序、希尔排序,快速排序将在后续更新。本文实现代码调用方法,部分来自前一个文章:简单排序算法之冒泡、...

Excel办公应用:按合并单元格排序的三大方法

1.按姓名对科目排序重点:在"C2"中输入公式=IF(A2<>"",1,C1+1),然后下拉填充。2.按姓名添加连续序号(方法一)重点:选择"A2:A11"单元格区域,在编辑栏中输入公...

快速排序 Vs. 归并排序 Vs. 堆排序——谁才是最强的排序算法

知乎上有一个问题是这样的:堆排序是渐进最优的比较排序算法,达到了O(nlgn)这一下界,而快排有一定的可能性会产生最坏划分,时间复杂度可能为O(n^2),那为什么快排在实际使用中通常优于堆排序?昨天刚...

归并排序思路图解 #归并排序_归并排序百度百科

排序算法1.图解。OK,让它排一下。看好了,要开始排了。能看出来像递归吗?肯定算法难,但是这个次数非常的多,不用管次数。这个是帝规,就是递归。这是并,这是并,这是两个有序数,组合成一个最后的大的有序数...

排序算法学习——归并排序_归并排序算法稳定吗

我们先看归并排序的定义归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每...

动画|经典的归并排序究竟怎么玩儿?

作者|菠了个菜责编|郭芮由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列——《图解数据结构》,主要使用动画来描述常见的数据...

Excel中,多列数据统一排名,Rank函数直接搞定

Rank实现多列联合排序排序,那太简单啦,Excel中,升序降序,一个按键就可以。但,那是针对单列情况,若需要联合多列数据进行排序呢?如下图所示,需要对1、3、5列进行统一排序,咋弄嘞?联合排序案例先...

【数据结构与算法】归并排序_数据结构中归并排序

归并排序是建立在归并操作的一种高效的排序方法,该方法采用了分治的思想,比较适用于处理较大规模的数据,但比较耗内存,今天我们聊聊归并排序排序思想一天,小一尘和慧能坐在石头上,眺望着远方师傅,我听山下的柳...

C++基础算法:归并排序_经典排序算法-----归并排序(c语言实现)

归并排序(MergeSort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。...

马士兵说之归并排序_马士兵教育的内推是真的

大家对于排序应该是挺熟悉的吧,马士兵老师特意为排序出了一波视频,当然文章是转自博客园的,马士兵老师的视频观看请点击下方的了解更多概要本章介绍排序算法中的归并排序。内容包括:1.归并排序介绍2.归并...

C++快速排序和归并排序_c++快速排序sort

快速排序每一轮挑选一个基准元素(随机选择,编程时一般选取第一个),并让比它大或小的元素移动到基准元素的两边,把数列拆解成了两个部分。而后对这两部分分别进行快速排序。时间复杂度:O(nlogn),辅助空...

经典的排序算法——归并排序_归并排序算法步骤

归并排序(MergeSort)是一种基于分治策略的高效排序算法。它将原始数组不断地分割成两个子数组,直到每个子数组只剩下一个元素为止(即基本有序),然后再通过合并已排序的子数组来最终得到完全有序的大...

归并排序_归并排序c++实现

归并排序概念:归并排序中涉及到一个概念就是分而治之,总序列化成小序列,将小序列排序好,利用排序好的小序列,再归并排序成原来要排序的序列。所以排序前先要分:functiondivide(arr){...

取消回复欢迎 发表评论: