本文首发于 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 联系。

Elasticsearch搜索调优权威指南 (2/3)的更多相关文章

  1. Elasticsearch搜索调优权威指南 (1/3)

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/qwkZKLb_ghmlwrqMkqlb7Q英文原文:https://qbox.io/blog/ela ...

  2. Elasticsearch搜索调优

    最近把搜索后端从AWS cloudsearch迁到了AWS ES和自建ES集群.测试发现search latency高于之前的benchmark,可见模拟数据远不如真实数据来的实在.这次在产线的bac ...

  3. Linux系统调优权威指南

    1.关闭SELINUX功能1.1 修改配置文件,使关闭SELINUX永久生效sed 's#SELINUX=enforcing#SELINUX=disables#g' /etc/selinux/conf ...

  4. elasticsearch性能调优

    转载 http://www.cnblogs.com/hseagle/p/6015245.html 该es调优版本可能有低,但是思想主体不变,不合适的参数可以自己找最新的版本相应的替代,或者增删 ela ...

  5. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码):http://www.2cto.com/kf/201607/528771.html https://www.zhihu.com/question/ ...

  6. 【转】XGBoost参数调优完全指南(附Python代码)

    xgboost入门非常经典的材料,虽然读起来比较吃力,但是会有很大的帮助: 英文原文链接:https://www.analyticsvidhya.com/blog/2016/03/complete-g ...

  7. elasticsearch 性能调优

    所有的修改都可以在elasticsearch.yml里面修改,也可以通过api来修改.推荐用api比较灵活 1.不同分片之间的数据同步是一个很大的花费,默认是1s同步,如果我们不要求实时性,我们可以执 ...

  8. XGBoost参数调优完全指南

    简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据.构造一个使用XGBoost ...

  9. 腾讯健康码16亿亮码背后的Elasticsearch系统调优实践【>>戳文章免费体验Elasticsearch服务30天】

    [活动]Elasticsearch Service免费体验馆>>Elasticsearch Service新用户特惠狂欢低至4折>>Elasticsearch Service企 ...

随机推荐

  1. flex——justify-content属性引起的一个样式问题

     前言  在flex布局出现以前,我一般习惯使用浮动布局(float)来实现下列布局   现在尽量少用浮动布局,虽然好用,但有时会带来一些意想不到的问题,甚至导致布局错位,   一开始浮动布局只是为了 ...

  2. 黄聪:Mysql开启InnoDB引擎出现1067错误的解决办法

    在my.ini文件添加下面这行: innodb_force_recovery = 1 可以解决:InnoDB: Attempted to open a previously opened tables ...

  3. 死磕 java同步系列之StampedLock源码解析

    问题 (1)StampedLock是什么? (2)StampedLock具有什么特性? (3)StampedLock是否支持可重入? (4)StampedLock与ReentrantReadWrite ...

  4. layui 使用随记

    layui confir使用 不显示右上角关闭按钮 针对提示框内按钮指定操作 layer.confirm("这里填写提示信息", {closeBtn:0,icon: 0, titl ...

  5. [b0029] python 归纳 (十四)_队列Queue实现生产者消费者

    # -*- coding: UTF-8 -*- """ 多线程的生产者,消费者 使用队列Queue """ import Queue imp ...

  6. [b0024] python 归纳 (十)_线程 _Thread模块

      #!/usr/bin/pythonn # -*- coding: UTF-8 -*- """ 学习线程 thread 总结: 1. 主线程退出,所有子线程都退出 2. ...

  7. 类,接口,final

    继承extends 子类实例化过程: 子类中所有的构造方法默认都会访问父类中空参的构造方法 因为每一个子类的构造方法的提议行都有一条默认的语句super(); this super final修饰类, ...

  8. 更改docker默认网段

    #本文档旨在说明创建docker时注意的事项:我们在局域网中使用Docker,最常遇到的一个困惑,就是有时候跨网段结果出现网络不通.原因是因为Docker默认生成的网关和我们的局域网网段有时候是冲突的 ...

  9. liteos分散加载(十四)

    1. 概述 1.1 基本概念 分散加载是一种实现特定代码快速启动的技术,通过优先加载特定代码到内存,达到缩短从系统开机到特定代码执行的时间.可被应用来实现关键业务的快速启动. 嵌入式系统通过uboot ...

  10. 5-6 可视化库Seaborn-Facetgrid使用和绘制多变量

      基本工作流程是FacetGrid使用数据集和用于构造网格的变量初始化对象.然后,可以通过调用FacetGrid.map()或将一个或多个绘图函数应用于每个子集 FacetGrid.map_data ...