优化elasticSearch(ES)的查询性能涉及多个方面,从查询本身到硬件资源,集群配置。
1,集群和硬件优化
-
硬件优化: 西安则高性能的硬件设备,例如 增加CPU ,内存,存储, 以提供更快的搜索速度和更大的容量。
-
负载均衡:确保查询负载在集群中均衡分配。Elasticsearch(ES)通过分布式架构和负载均衡机制来实现数据的分片和负载均衡。
-
分片:ES将索引的数据划分为多个分片(shard),每个分片存储部分数据。分片可以水平扩展到多个节点上,从而实现数据的并行处理和负载均衡。分片的数量和副本的数量可以在索引创建时进行配置,通常配置的分片数量是根据数据量和并发查询的需求来确定的。
-
负载均衡:ES通过协调节点(coordinating node)实现负载均衡。协调节点是客户端与索引节点(index node)之间的中介节点,负责接收客户端的请求,并将请求转发到包含所需数据分片的索引节点上进行处理。当索引节点的负载过高或出现故障时,协调节点可以将请求转发到其他可用的索引节点上,从而实现负载均衡和高可用性。
-
节点通信:ES集群中的各个节点通过节点间通信(Node-to-Node communication)进行数据同步和协调。例如,当某个节点有新的数据写入或索引创建时,它会将数据变更通知给其他节点,使得其他节点能够进行相应的数据同步和分片的重新分配。这样可以保证数据的一致性和负载的均衡。
-
节点选择策略:ES提供了多种节点选择策略来实现负载均衡。常见的策略有轮询(round-robin)、最少连接数(least_connected)和可用性优先(availability)等。通过选择合适的节点选择策略,可以根据集群的状态和负载情况来决定请求的转发目标,从而实现负载均衡和高效查询。
-
总而言之,ES通过分片的方式将索引的数据分布到多个节点上,并通过协调节点进行请求的转发和负载均衡,从而实现高性能、高可用性的负载均衡机制。
-
合理的参数配置:通过配置JVM(Java Virtual Machine),可以对Elasticsearch(ES)进行搜索性能优化。以下是一些常见的JVM配置优化项:
-
堆内存设置:ES使用堆内存来存储索引数据和执行搜索操作。通过适当配置堆内存大小,可以避免过度分配或不足的问题。可以通过设置-Xms和-Xmx参数来指定堆内存的初始大小和最大大小。根据集群的规模和服务器的配置,需要根据具体情况进行优化。
-
垃圾回收策略:ES默认使用的是G1垃圾回收器。可以通过设置-XX:+UseG1GC参数来启用G1垃圾回收器,并使用-XX:G1HeapRegionSize参数设置G1的堆区域大小。另外,根据实际情况可以调整其它相关的垃圾回收配置参数,例如-XX:MaxGCPauseMillis来控制垃圾回收暂停的时间。
-
线程池和并发度设置:ES中的搜索操作会涉及到线程的并发处理。可以通过配置线程池和并发度参数,来控制并发搜索请求的处理。例如,可以通过设置thread_pool.search.size参数来增加搜索线程池的大小,来提高并发搜索的处理能力。
-
内存分配比例调整:ES使用内存池(mmapfs)来存储索引数据,可以通过调整内存池的分配比例来提升搜索性能。可以通过设置-Des.index.store.type=mmapfs来启用内存池,并使用-Des.index.store.fs.mmapfs.memory参数来调整分配的内存大小。
-
监控和调优:对于JVM的性能优化,尤其是垃圾回收的调优,需要进行实时监控和性能分析,以找到性能瓶颈,并进行相应的调整。可以使用工具如Elasticsearch的内置监控和性能分析工具,如hot_threads API、gc日志和JVM监控工具(例如JVisualVM、VisualVM等)来进行监控和调优。
2,合理分片和副本
虽然更过的分片可以提高写入吞吐量,因为可以并行写入多个分片。但是,查询大量分片可能会降低查询性能,因为每个分片都需要单独处理查询。而且分片数量过多可能会增加集群的管理开销和降低查询效率,尤其是在内存和文件句柄方面。所以需要考虑数据量和硬件资源,合理设置分片数量。
那么具体如何设置分片和副本数量呢? 目前来看没有一种可以通用的设置方法。都要根据数据的大小,查询的复杂性,硬件资源和预期负载等多维度总喝考虑。
1,在ES 每个节点上可以存储的分片数量与可用的堆内存大小成正比。 ES 并未强制规定固定值限制。目前可以参考一下方法。 确保对于节点上已配置的每个GB ,将分片数量保持在20以下。 例如 如果节点 有 16G 的堆内存, 那么最多可以有 320个分片。 节点上分片过多过少都会有问题。合理配置保持在一个健康范围内很重要。
3,精确的映射和索引设置
精确的映射和索引设置是优化ES搜索性能和查询准确性的关键。通过正确定义字段映射、选择合适的字段索引类型、配置适当的分词器、使用精确匹配和过滤,以及优化索引级别设置,可以提高索引和搜索操作的效率和准确性。
-
映射定义:映射是定义索引中字段的类型和属性的过程。确保为每个字段设置正确的数据类型,例如字符串、数字、日期等,以及适当的数据格式和分析器。正确的映射能够更好地理解和处理文本内容,提高搜索和聚合的准确性。
-
字段索引:根据字段的特性和查询需求,选择合适的字段索引类型。ES提供了多种索引类型,包括全文索引、关键字索引、日期索引等。仔细考虑字段的搜索、聚合和排序需求,选择合适的索引类型来优化查询性能。
-
分词器设置:分词器决定了如何将文本切分成词(terms)来进行索引和搜索。选择合适的分词器对于不同语言、文本类型和查询需求非常重要。ES提供了多种内置的分词器,如标准分词器(standard tokenizer)、中文分词器(ik analyzer)等。根据实际情况选择和配置适当的分词器,以确保索引和搜索的准确性和一致性。
-
精确匹配和精确过滤:对于需要精确匹配的字段,可以使用关键字索引类型来进行精确匹配或过滤。关键字索引类型适用于不需要进行分词和分析的字段,主要用于精确匹配或过滤查询。通过正确设置字段的映射和索引类型,可以有效提高精确匹配操作的性能和精确度。
-
词条查询和过滤:词条查询(term query)和词条过滤(term filter)是进行精确匹配的常用操作。词条查询和过滤不会对查询词进行分词处理,可以更准确地匹配字段中的词条。通过在查询和过滤操作中使用词条查询和过滤,可以提高查询的准确性和性能。
-
索引设置:ES提供了各种索引级别的设置,例如文档数限制、内存缓存、刷新频率等。根据具体的业务需求和硬件资源,进行适当的索引设置,以平衡索引写入和查询性能。
4,查询优化
有些人用es 很慢,是因为自己的查询本身就用的不对。
-
使用过滤器(Filter)而不是查询(Query):如果你需要执行精确匹配或范围过滤的操作,尽量使用过滤器。过滤器可以缓存查询结果,减少重复计算,提高性能。而查询会对每个匹配的文档进行计算分数,消耗更多的资源。
-
避免全文搜索的通配符查询:通配符查询(Wildcard Query)和正则表达式查询(Regexp Query)可以进行灵活的模式匹配,但通常较慢,会增加搜索时间。尽量避免在查询中使用通配符查询,或者合理地使用通配符前缀查询(Wildcard Prefix Query)。
-
利用索引:根据具体的查询需求使用正确的索引。ES提供了多种索引类型,如关键字索引、全文索引和地理位置索引等。确保选择和配置适当的索引类型,以提高搜索和过滤操作的性能。
-
建立合适的分片数量:在设计索引时,考虑数据的规模和查询的并发需求。合适的分片数量可以充分利用集群资源,提高查询和索引的并行处理能力。
-
缓存经常使用的查询:ES提供了查询缓存的功能,可以缓存经常使用的查询结果,提高查询性能。对于一些频繁访问的查询,可以考虑开启查询缓存。
-
使用合适的排序方式:排序操作会消耗一定的资源。对于频繁使用的排序操作,可以考虑使用Field Data的方式进行排序,或者合理选择ES中提供的各种排序方式。
-
监控和优化查询性能:通过监控查询性能指标,如查询响应时间、资源使用情况等,可以及时发现性能瓶颈和优化的空间。根据监控结果进行索引和查询优化,以提升整体系统的性能。
-
查询尽可能少的字段:只返回查询中需要的字段,减少数据传输和处理时间。
-
避免使用脚本:尽量避免使用脚本 Script 查询,因为他们通常比简单查询要慢
-
避免深度分页:避免深度分页,对于需要处理大量数据的情况,考虑使用search_after
-
使用match 而非 term 查询文本字段: match 查询会分析查询字符串,而term 查询不会,适用于精确匹配
-
避免使用通配符,正则表达式: 这类查询往往非常消耗资源,特别是通配符开头的。
-
合理使用聚合: 集合可以用于高效地进行数据分析,但复杂的聚合也可能非常的消耗资源。优化聚合查询,如通过限制桶的数量 避免过度复杂的嵌套聚合