ES 优化概述|学习笔记

本文涉及的产品
Elasticsearch Serverless通用抵扣包,测试体验金 200元
简介: 快速学习 ES 优化概述。

开发者学堂课程【ElasticSearch 最新快速入门教程ES 优化概述】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/642/detail/10682


ES 优化概述

 

内容介绍:

一、硬件环境的选择

二、系统拓扑设计

三、ES 的内存设置

四、集群分片设置

五、Mapping 建模

六、索引优化设置

七、查询优化

八、集群运营与恢复

 

Elasticsearch 是目前大数据领域最热门的的技术栈之一,经过近8年的发展,已从0.0.X版升级至7.X版本,增加了很多特性和功能,但是在主体架构上,还是没有太多的变化。

 

一、硬件环境的选择

如果有可能,尽可能 SSD 硬盘以及较为强悍的 CPU。ES 的厉害之处在于 ES 本身的分布式架构以及 lucene 的特性。值函数的输出,IO 的提升,会极大改进 ES 的速度和性能。

 

二、系统拓朴设计

ES 集群在架构拓扑时,一般都会采用 Hot-Warm 的架构模式,即设置3种不同类型的节点:Master 节点、Hot 节点和 Warm 节点。

1. Master 节点设置

一般会设置3个专用的 master 节点,以提供最好的弹性当然,必须注意 discovery.zen.minimum_master nodes 属性的设置,以防 split-brain 问题,使用公式设置:

N/2+1(N为候选 master 节点数)。该节点保持:node.data:false;因为 master 节点不参与查询、索引操作,仅负责对于集群管理所以在 CPU、内存、磁盘配置上,都可以比数据节点低很多。

2. Hot 节点设置

又称索引节点(写节点),专用于数据储存的节点,同时近期频繁使用的索引都会保存在 Hot 节点中。属于 IO 和 CPU密集型操作,建议使用SSD固态硬盘的磁盘类型,保持良好的写性能;节点的数量设置一般是大于等于3个。将节点设置为 hot 类型:node.attr.box_type: hot。针对 index,通过设置

index.routing.allocation.require.box_

type:hot 可以设置将索引写入 hot 节点。

3. Warm 节点设置

用于不经常访问的 read-only 索引。由于不经常访问,一般使用普通的磁盘即可。内存、CPU 的配置跟 Hot 节点保持一致即可;节点数量一般也是大于等于3个。

当索引不再被频繁查询时,可通过

index.routing.allocation.require.box_type:warm,将索引标记为 warm,从而保证索引不写入 hot 节点,以便将 SSD 磁盘资源用在刀刃上。一旦设置这个属性,ES 会自动将索引合并到 warm 节点。同时,也可以在elasticsearch.yml 中设置 index.codec:best compression 保证 warm 节点的压缩配置。

4. Coordinating 节点

协调节点用于做分布式里的协调,将各分片或节点返回的数据整合后返回。

在ES集群中,所有的节点都有可能是协调节点,但是,可以通过设置 node.master、nodedata、node.ingest 都为false 来设置专门的协调节点,需要较好的 CPU 和较高的内存。

 

三、ES 的内存设置

由于 ES 构建基于 lucene,而 lucene 设计强大之处在于 lucene 能够很好的利用操作系统内存来缓存索引数据,以提供快速的查询性能。lucene 的索引文件 segements 是存储在单文件中的,并且不可变,对于 OS 来说,能够很友好地将索引文件保持在 cache 中,以便快速访问;因此,我们很有必要将一半的物理内存留给 lucene;另一半的物理内存留给 ES(JVM heap)。

所以,在 ES 内存设置方面,可以遵循以下原则:

1. 当机器内存小于64G 时,遵循通用的原则,50%给 ES,50%留给 lucene。

2.当机器内存大于64G 时,遵循以下原则:

(1)如果主要的使用场景是全文检索,那么建议给 ESHeap 分配4~32G 的内存即可;其它内存留给操作系统,供1ucene 使用(segments cache),以提供更快的查询性能。

(2)如果主要的使用场景是聚合或排序,并且大多数是 numerics,dates,geo_points 以及 not_analyzed的字符类型,建议分配给 ES Heap 分配4~32G 的内存即可,其它内存留给操作系统,供1ucene 使用(doc values cache),提供快速的基于文档的聚类、排序性能。

(3)如果使用场景是聚合或排序,并且都是基于 analyzed 字符数据,这时需要更多的 heap size,建议机器上运行多 ES 实例,每个实例保持不超过50%的 ESheap 设置(但不超过32G,堆内存设置32G以下时,JVM 使用对象指标压缩技巧节省空间),50%以上留给lucene。

3.禁止 swap,一旦允许内存与磁盘的交换,会引起致命的性能问题。通过:在 elasticsearch.yml 中 bootstrap.memory_lock:true,以保持 JVM 锁定内存,保证 ES 的性能,实现内存与磁盘的交互。

4.GC 设置原则:

(1)保持 GC 的现有设置,默认设置为:Concurrent-Mark and Sweep(CMS),别换成 G1GC,因为目前 G1还有很多 BUG。

(2)保持线程池的现有设置,目前 ES 的线程池较1.x 有了较多优化设置,保持现状即可;默认线程池大小等于 CPU 核心数。

如果一定要改,按公式((CPU 核心数*3)/2)+1设置;不能超过 CPU 核心数的2倍;但是不建议修改默认配置,否则会对CPU 造成硬伤。

 

四、集群分片设置

ES 一旦创建好索引后,就无法调整分片的设置,而在 ES 中,一个分片实际上对应一个 lucene 索引,而 lucene 索引的读写会占用很多的系统资源,因此,分片数不能设置过大;所以,在创建索引时,合理配置分片数是非常重要的。

一般来说,我们遵循一些原则:

1. 控制每个分片占用的硬盘容量不超过 ES 的最大 JVM 的堆空间设置(一般设置不超过32G,参加上文的 JVM 设置原则),因此,如果索引的总容量在500G 左右,那分片大小在16个左右即可;当然,最好同时考虑原则2。

2.考虑一下 node 数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以,一般都设置分片数不超过节点数的3倍。


五、 Mapping 建模

1.尽量避免使用 nested(嵌套)或 parent/child(父子关系),能不用就不用;nested query 慢,parent/child query 更慢,比 nested query 慢上百倍;因此能在 mapping 设计阶段搞定的(大宽表设计或采用比较 smart 的数据结构),就不要用父子关系的 mapping。

2.如果一定要使用 nestedfields,保证 nestedfields 字段不能过多,目前 ES 默认限制是50。参考: index.mapping.nested_fields.lim

it :50。因为针对1个 document,每一个 nestedfield,都会生成一个独立的 document,这将使 Doc 数量剧增,影响查询效率,尤其是 JOIN 的效率。

3. 避免使用动态值作字段(key),动态递增的 mapping,会导致集群崩溃;同样,也需要控制字段的数量,业务中不使用的字段,就不要索引。控制索引的字段数量、mapping 深度、索引字段的类型,对于 ES 的性能优化是重中之重。以下是 ES 关于字段数、mapping 深度的一些默认设置:

index.mapping nested_objects.limit:10000 index.mapping.total_fields.limit:1000 index.mapping.depth.limit: 20

 

六、索引优化设置

1.设置 refresh_interval 为-1,同时设置 number_of_replicas 为0,通过关闭 refresh 间隔周期,同时不设置副本来提高写性能。

2.修改 index_buffer_size 的设置,可以设置成百分数,也可设置成具体的大小,大小可根据集群的规模做不同的设置测试.

indices.memory.index_buffer size:10%(默认)

indices.memory.min_index_buffer_size: 48mb(默认) indices.memory.max_index_buffer_size

3.修改 translog 相关的设置:

(1)控制数据从内存到硬盘的操作频率,以减少硬盘I0。可将 sync_interval 的时间设置大一些 index.translog.sync_interval: 5s(默认)

(2)控制 tranlog 数据块的大小,达到 threshold 大小时,才会 flush 到 lucene 索引文件。

index.translog.flush_threshold_size:512mb(默认)

4. id 字段的使用,应尽可能避免自定义 d,以避免针对 ID 的版本管理;建议使用 ES 的默认!D 生成策略或使用数字类型ID 做为主键。

5. all 字段及 source 字段的使用,应该注意场景和需要,all 字段包含了所有的索引字段,方便做全文检索,如果无此需求,可以禁用;source 存储了原始的 document 内容,如果没有获取原始文档数据的需求,可通过设置 includes、excludes 属性来定义放入 source 的字段。

6.合理的配置使用 index 属性,analyzed 和 not analyzed,根据业务需求来控制字段是否分词或不分词。只有groupby 需求的字段,配置时就设置成 not_analyzed,以提高查询或聚类的效率。

 

七、查询优化

1.query_string 或 multi_match的查询字段越多,查询越慢。可以在 mapping 阶段,利用 copy_to 属性将多字段的值索引到一个新字段,multi_match 时,用新的字段查询。

2.日期字段的查询,尤其是用 now 的查询实际上是不存在缓存的,因此,可以从业务的角度来考虑是否一定要用now,毕竟利用 query

cache 是能够大大提高查询效率的。

3.查询结果集的大小不能随意设置成大得离谱的值,如 query.setSi

ze 不能设置成 Integer.MAX_VALUE,因为 ES 内部需要建立一个数据结构来放指定大小的结果集数据。若设置的值过大,可能会导致内存崩溃。

6. 尽量避免使用 script(脚本),万不得已需要使用的话,选择 painl

ess&experssions 引擎。一旦使用 script 查询,一定要注意控制返回,千万不要有死循环(如下错误的例子),因为 ES没有脚本运行的超时控制,只要当前的脚本没执行完,该查询会一直阻塞。

如:

{

"script_fields" : {

"test1" : {

"lang”:“groovy”,

"script":"while(true){print 'don't use script'}"

}

}

}

5. 避免层级过深的聚合查询,层级过深的 groupby,会导致内存、CPU 消耗,建议在服务层通过程序来组装业务,也可以通过 pipeline 的方式来优化。

6.复用预索引数据方式来提高 AGG 性能:如通过 terms aggregatio

ns 替代 range aggregations,如要根据年龄来分组,分组目标是:少年(14岁以下)青年(14-28)中年(29-50)老年(51以上),可以在索引的时候设置一个 age_group 字段,预先将数据进行分类。从而不用按 age 来做 range aggregations,通过 agegroup 字段就可以了。

7.Cache 的设置及使用:

(1)QueryCache:ES 查询的时候,使用 filter 查询会使 querycache,如果业务场景中的过滤查询比较多,建议将 querycache 设置大一些,以提高查询速度。indices.queries.cache.size:10%(默认),可设置成百分比,也可设置成具体值,如256mb。当然也可以禁用查询缓存(默认是开启),通过 index.queries.cache.enabled: false 设置。

(2)FieldDataCache:在聚类或排序时,field datacache 会使用频繁,因此,设置字段数据缓存的大小,在聚类或排序场景较多的情形下很有必要,可通过 indices.fielddata.cache.size:30%或具体值10GB 来设置。但是如果场景或数据变更比较频繁,设置 cache 并不是好的做法,因为缓存加载的开销也是特别大的。

(3)ShardRequestCache:查询请求发起后,每个分片会将结果返回给协调节点(Coordinating Node),由协调节点将结果整合。

如果有需求,可以设置开启;通过设置index.requests.cache.enabl

e:true 来开启。不过,shard request cache 只缓存 hits.total,aggre

gations,suggestions 类型的数据,并不会缓存 hits 的内容也可以通过设置 indices.requests.cache.size;1%(默认)来控制缓存空间大小。

 

八、集群运营与恢复

该部分内容之前的课程中已有涉及,此处不多加赘述。

相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
中间件 数据库连接 API
Python面试:FastAPI框架原理与实战
【4月更文挑战第18天】FastAPI是受欢迎的高性能Python Web框架,以其简洁的API设计、强大的类型提示和优秀的文档生成能力著称。本文将探讨FastAPI面试中的常见问题,包括路由、响应对象、Pydantic模型、数据库操作、中间件和错误处理。同时,还会指出一些易错点,如类型提示不准确、依赖注入误解,并提供实战代码示例。通过理解和实践FastAPI,可以在面试中展示出色的Web开发技能。
558 1
|
数据可视化 前端开发 Java
ElasticSearch可视化管理工具cerebro的安装与简单使用
ElasticSearch可视化管理工具cerebro的安装与简单使用
1859 0
ElasticSearch可视化管理工具cerebro的安装与简单使用
|
应用服务中间件 索引 nginx
生产环境ES查询延迟排查
最近经常收到业务方配置的ES查询延迟告警,同样的请求手动在Kibana控制台执行只需几十毫秒就返回结果。受影响的整个链路情况如下,php应用程序通过部署在ES集群各节点上的nginx访问ES请求查询数据。
5622 0
|
存储 缓存 自然语言处理
Elasticesearch内存详解
Elasticesearch内存详解总结文章
4805 0
Elasticesearch内存详解
|
7月前
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
248 27
|
9月前
|
存储 搜索推荐 关系型数据库
ElasticSearch 详解
ElasticSearch 是一款优秀的开源搜索引擎,适用于大数据场景下的高效检索与分析。其分布式架构、实时搜索和灵活的数据分析功能使其能处理 PB 级数据量。相比 Solr,ES 在实时性、分布式架构和文档处理上更具优势。核心概念包括索引、文档、分片和副本等。ES 使用倒排索引实现快速搜索,区别于正向索引。与关系型数据库相比,ES 更适合非结构化数据和全文搜索。总结来说,ES 在电商搜索、日志分析等领域有广泛应用,未来有望带来更多创新。
433 19
|
消息中间件 存储 RocketMQ
消息中间件-RocketMQ技术(二)
消息中间件-RocketMQ技术(二)
|
12月前
|
消息中间件 存储 Java
RocketMQ(一):消息中间件缘起,一览整体架构及核心组件
【10月更文挑战第15天】本文介绍了消息中间件的基本概念和特点,重点解析了RocketMQ的整体架构和核心组件。消息中间件如RocketMQ、RabbitMQ、Kafka等,具备异步通信、持久化、削峰填谷、系统解耦等特点,适用于分布式系统。RocketMQ的架构包括NameServer、Broker、Producer、Consumer等组件,通过这些组件实现消息的生产、存储和消费。文章还提供了Spring Boot快速上手RocketMQ的示例代码,帮助读者快速入门。
|
机器学习/深度学习
YOLOv8改进 | 细节创新篇 | iAFF迭代注意力特征融合助力多目标细节涨点
YOLOv8改进 | 细节创新篇 | iAFF迭代注意力特征融合助力多目标细节涨点
939 0
|
边缘计算 Kubernetes Linux
KubeSphere平台安装系列之三【Linux多节点部署KubeSphere】(3/3)
KubeSphere平台安装系列之三【Linux多节点部署KubeSphere】(3/3)
317 1