Post

如何优化 ElasticSearch 搜索性能?

如何优化 ElasticSearch 搜索性能?

如何优化 ElasticSearch 搜索性能?

典型回答

优化 Elasticsearch(ES)的查询性能涉及多个方面,从查询本身到集群配置和硬件资源。以下是一些关键的优化策略:

集群和硬件优化

  • 负载均衡: 确保查询负载在集群中均衡分配。
  • 硬件资源: 根据需要增加 CPU、内存或改善 I/O 性能(例如使用 SSD)。
  • 配置 JVM: 优化 JVM 设置,如堆大小,以提高性能。

合理分片和副本

虽然更多的分片可以提高写入吞吐量,因为可以并行写入多个分片。但是,查询大量分片可能会降低查询性能,因为每个分片都需要单独处理查询。而且分片数量过多可能会增加集群的管理开销和降低查询效率,尤其是在内存和文件句柄方面。所以,需要考虑数据量和硬件资源,合理设置分片数量。

但是这个说起来比较玄学,毕竟没有一种”一刀切”的方法来确定最优的分片和副本数量,因为这取决于多种因素,包括数据的大小、查询的复杂性、硬件资源和预期的负载等。

在ES每个节点上可以存储的分片数量与可用的堆内存大小成正比关系,但是 Elasticsearch 并未强制规定固定限值。这里有一个很好的经验法则:确保对于节点上已配置的每个 GB,将分片数量保持在 20 以下。如果某个节点拥有 30GB 的堆内存,那其最多可有 600 个分片,但是在此限值范围内,您设置的分片数量越少,效果就越好。一般而言,这可以帮助集群保持良好的运行状态。(来源参考:https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster

精确的映射和索引设置

映射(Mapping)是定义如何存储和索引文档中字段的规则。我们可以在以下几个方面做一些优化:

确切定义字段类型:为每个字段指定正确的数据类型(如 text, keyword, date, integer 等),这是因为不同的数据类型有不同的存储和索引方式。需要注意的是:text 类型用于全文搜索,它会被分析(analyzed),即分解为单个词项。keyword 类型用于精确值匹配,过滤,排序和聚合。它不会被分析。

根据需要选择合适的分析器(Analyzer),对于 text 类型的字段,可以指定分析器来定义文本如何被分割和索引。对于不需要全文搜索的字段,使用 keyword 类型以避免分析开销。

查询优化

很多人用ES很慢,是因为自己的查询本身就用的不对,我们可以尝试着优化一下你的查询。如:

  • 避免高开销查询: 如 wildcardregexp 等类型的查询往往开销较大,尽量避免使用或优化其使用方式。
  • 使用过滤器: 对于不需要评分的查询条件,使用 filter 而不是 query,因为 filter 可以被缓存以加快后续相同查询的速度。
  • 查询尽可能少的字段: 只返回查询中需要的字段,减少数据传输和处理时间。
  • 避免深度分页: 避免深度分页,对于需要处理大量数据的情况,考虑使用 search_after
  • 避免使用脚本:尽量避免使用脚本(Script)查询,因为它们通常比简单查询要慢。(脚本执行通常比静态查询更消耗资源。每次执行脚本时,都需要进行编译(除非缓存)和运行,这会增加CPU和内存的使用。脚本执行不能利用索引,因此可能需要全面扫描文档。)
  • 使用 match 而非 term 查询文本字段:match 查询会分析查询字符串,而 term 查询不会,适用于精确值匹配。
  • 避免使用通配符、正则表达式:这类查询往往非常消耗资源,特别是以通配符开头的(如 *text)。
  • 合理使用聚合:聚合可以用于高效地进行数据分析,但复杂的聚合也可能非常消耗资源。优化聚合查询,如通过限制桶的数量,避免过度复杂的嵌套聚合。

使用缓存

  • 请求缓存: 对于不经常变化的数据,利用 ES 的请求缓存机制。
  • 清理缓存: 定期清理不再需要的缓存,释放资源。

监控和分析

  • 监控: 使用 Kibana、Elasticsearch-head、Elastic HQ 等工具监控集群状态和性能。
  • 慢查询日志: 启用慢查询日志来识别和优化慢查询。

###

This post is licensed under CC BY 4.0 by the author.