这样优化Elasticsearch,显著提升查询速度

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: elasticsearch的搜索效率与多方面有关,例如系统资源、数据查询方式、数据索引方式等,本文从各方面讨论如何进行搜索速度的优化,提升查询的性能。

elasticsearch的搜索效率与多方面有关,例如系统资源、数据查询方式、数据索引方式等,本文从各方面讨论如何进行搜索速度的优化,提升查询的性能。

01

预留足够的堆外内存

首先,操作系统普通的文件读写会经过Page   Cache,从而加速文件的访问,一旦命中缓存可以现实提升读写速度,这部分使用的就是堆外内存。elasticsearch底层是lucene,涉及到大量的索引文件的读写,所以必须预留足够的堆外内存以供文件系统的访问使用。其次,elasticsearch默认的存储方式index.store.type是hybridfs,它是niofs和mmapfs的组合,目前term、norms、doc  values使用的是mmapfs,实际映射到了Lucene  MMapDirectory数据结构,而其他的则是使用了niofs的存储方式,实际映射到Lucene NIOFSDirectory。

通过MMapfs方式的,会将文件映射到内存,索引数据会被预加载到操作系统的Page Cache中,而如果能够使用Page Cache,则直接查询内存,避免通过I/O读取,查询速度会更快(这不是绝对的,后续专门针对MMapfs再展开细节)

最后要注意的是,当内存不足时会导致swap的发生,内存的换入换出会导致大量的I/O,查询速度会严重下降,一般情况下建议在生产上禁用swap或者配置swappiness为较小的值,例如1,降低swap的趋势,也可以通过设置elasticsearch的bootstrap.memory_lock:  true锁定内存,禁止swap。

02

使用SSD替换普通机械磁盘

当存在大量的查询请求时,磁盘IO压力会显著增加,在SSD资源有限的情况下,可以进行数据的冷热分离,将高频查询的数据放到SSD上。

03

禁用复杂的文档模型

一般情况下,禁止使用nested、partent-child这种文档模型,因为他们会严重影响查询性能。parent-child只适用于一对多的关系,且父子关系文档数据量差别很大的情况,一旦确实使用了这种文档模型,但是查询性能又较差的时候,可以考虑增加主分片的数量,然后进行reindex。

04

定期进行forcemerge

定期对索引进行force merge,特别是对于一些没有写请求的历史索引,减少segments的数量,能够显著提高查询速度,因为索引段很多的情况下,查询时需要遍历所有的索引段,势必导致查询速度缓慢。

05

查询语句优化

  • 不要使用正则表达式查询
  • 尽量不要使用模糊匹配
  • 对于不需要使用评分机制的查询,使用filter替代query,一是可以减少打分的操作损耗,二是filter可以走Node Query Cache,查询速度更快。

06

字段冗余

利用一些富化、冗余字段来支持一些范围聚合查询,类比关系数据库中配置一些冗余字段减少join操作,因为这些操作的成本都比较高。

07

增加协调节点

elasticsearch协调节点负责转发请求到各个数据节点,然后对结果进行汇总整合,如果集群存在大量的查询操作且需要大量的数据聚合,则CPU和内存的压力都会比较大,这种情况下可以根据需要适当增加一些协调节点。

08

预热文件系统cache

如果elasticsearch主机重启,则文件系统缓存为空,此时的搜索会比较慢,可以使用index.store.preload设置,指定将哪些扩展名的文件加载到内存中.可以通过elasticsearch.yml指定全局的,也可以在创建索引时指定索引级别的配置。

  • 全局的配置
  • 索引级别的配置

09

开启ARS自适应副本机制

默认情况下,协调节点将请求简单轮训到每个分片副本上,而不管副本分片所在节点的实际负载情况,这样子就会导致某些情况下某些节点负载比较高,响应速度比较慢,在ES6.1以上的版本,这种情况下可以开启ARS,利用自适应副本选择机制,智能的选择将请求转发给负载较低的分片所在节点。

10

预热全局序号global ordinals

什么是global  ordinals呢?要理解global ordinals首先需要理解ordinals,  假设有n条数据,每条数据有一个字段fruit(keyword类型),其值有三种可能性:Orange、Apple、Peach,那么每条数据至少需要存储5-6个字符的长度,当数据量越来越大,则占用的内存会越来越高。

为了减少内存使用,考虑将字符串排序后进行编号,形成一张映射表,然后在每条数据中使用相应字符串的序号来表示,例如1-Orange,2-Apple,3-Peach,这里的映射表中的序列号就是ordinals。

当我们对fruit字段做Terms聚合时,请求会通过协调节点转发到各个数据节点分片上执行,Ordinals是针对segment级别的,针对Segment而言,同一个字符串在不同的segment  Ordinals中可能对应的序号是不同的,当查询完所有的segment以后就又涉及到整合合并,于是针对shard级别的global ordinals出现了,能够在shard级别上进行映射,一方面减少内存内存使用,另外一方面提升聚合的效率。

因为global ordinals面向的是shard级别,所以当一个Shard的Segment发生变动时就需要重新构建Global Ordinals,默认情况下global Ordinals是在收到聚合查询请求并且该查询会命中相关字段时构建,而创建或更新的时候需要一定的时间,特别是在数据量巨大的情况下,构建可能会花费比较长的时间,所以可以考虑在设置mapping的时候配置在refresh时告诉ES预先加载全局序号,减少在查询时创建或更新的时间,一定程度上提升查询速度。

这实际上是牺牲写入的效率从而提升查询的效率的一种方法。

11

使用execution hint配置terms聚合的机制

elasticsearch的terms聚合有两种方式:

  • 直接使用字段值进行聚合,也就是map
  • 使用global_ordinals,每个global_ordinals分配一个bucket,对bucket进行聚合

当存在数据量较大时,global_ordinals的方式效果明显,而当查询匹配的文档比较少的时候使用map直接聚合的效果比较好,因为不需要进行global_ordinals的构建。

12

查询语句分析

终极大招,如果如果语句查询很慢,但是不清楚原因,可以在query查询语句请求体上加上"profile":  "true",启用profile API,这样子可以看到一个搜索聚合请求,是如何拆分成底层的 Lucene  请求,并且显示每部分的耗时情况,以方便进一步分析,以下是对索引customer使用profile API进行分析的案例。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
27天前
|
存储 缓存 固态存储
优化Elasticsearch 硬件配置
优化Elasticsearch 硬件配置
73 5
|
1月前
|
缓存 监控 安全
Elasticsearch扩展和优化
【11月更文挑战第4天】
42 6
|
2月前
|
存储 自然语言处理 Java
Elasticsearch写入优化
【10月更文挑战第3天】Elasticsearch:从写入原理谈写入优化
96 2
|
27天前
|
存储 缓存 监控
优化Elasticsearch 索引设计
优化Elasticsearch 索引设计
22 5
|
27天前
|
缓存 监控 安全
优化Elasticsearch 集群配置
优化Elasticsearch 集群配置
63 4
|
28天前
|
监控 负载均衡 安全
Elasticsearch集群配置优化
Elasticsearch集群配置优化
29 1
|
28天前
|
存储 缓存 监控
优化 Elasticsearch
优化 Elasticsearch
23 1
|
2月前
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
56 4
|
2月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
55 0
|
2月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
38 0