优化ES搜索性能

时间:2024-04-29 15:09:18

最近做的舆情系统用到了ES,比数据库的效率要高得多,不过我也一直在顾虑经过长时间的运行之后数据编的特别多,到时ES也变得吃力,最近也有一些了解

优化ES主要从两方面考虑,硬件和软件

集群和硬件优化

使用更好的硬件肯定是能快速解决问题的,但是这需要钱,我们说了不算,所以主要还是从配置上来下功夫

合理分片和副本

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

精确的映射和索引设置

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

确切定义字段类型:为每个字段指定正确的数据类型(如 text, keyword, date, integer 等),这是因为不同的数据类型有不同的存储和索引方式。需要注意的是:text 类型用于全文搜索,它会被分析(analyzed),即分解为单个词项。keyword 类型用于精确值匹配,过滤,排序和聚合。它不会被分析。
根据需要选择合适的分析器(Analyzer),对于 text 类型的字段,可以指定分析器来定义文本如何被分割和索引。对于不需要全文搜索的字段,使用 keyword 类型以避免分析开销。

查询优化

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

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

使用缓存

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