MST

星途 面试题库

面试题:ElasticSearch如何优化大量数据搜索时的性能

在ElasticSearch处理大量数据搜索场景下,通常有哪些方面可以进行性能优化?请从索引设置、查询语句优化等方面阐述。
23.7万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

索引设置优化

  1. 字段映射优化
    • 数据类型选择:尽量使用能够准确表示数据且占用空间小的数据类型。例如,对于固定范围的整数,选择合适的整型(如 byteshort 等)而不是 long。对于不需要进行全文搜索的文本字段,使用 keyword 类型,这样可避免分词带来的性能损耗。
    • 动态映射:谨慎使用动态映射,避免因为自动映射生成不必要的字段。可以通过预定义字段映射来控制索引结构,减少不必要的字段和映射冲突。
  2. 索引分片与副本设置
    • 分片数量:根据数据量和集群规模合理设置分片数量。一般原则是每个分片大小控制在 10GB - 50GB 左右。如果数据量较小,过多的分片会增加集群管理开销;数据量较大时,分片过少会导致单个分片数据量过大,影响搜索性能。可以根据预估的数据量和节点数量,通过公式大致估算分片数。
    • 副本数量:副本主要用于提高数据可用性和搜索性能。适当增加副本数量可以提升读性能,但过多的副本会占用更多的磁盘空间和网络带宽,同时在数据写入时也会增加额外的同步开销。一般设置 1 - 2 个副本即可,根据实际业务对读写性能的要求进行调整。
  3. 索引存储优化
    • 存储类型选择:对于不同类型的数据,可以选择不同的存储类型。例如,对于一些很少更新但经常查询的索引,可以使用 doc_values 存储来加快排序和聚合操作;对于需要快速检索的文本字段,使用 fielddata(但要注意内存消耗)。
    • 压缩:开启索引数据的压缩,可以有效减少磁盘空间占用,提高磁盘 I/O 效率。Elasticsearch 支持多种压缩算法,如 LZ4DEFLATE 等,LZ4 算法在性能和压缩比之间有较好的平衡,通常是较好的选择。

查询语句优化

  1. 减少返回字段:尽量只返回需要的字段,避免返回所有字段(_source)。通过在查询语句中指定 _source 包含或排除某些字段,可以减少网络传输的数据量,提高查询性能。例如:
{
    "query": {
        "match_all": {}
    },
    "_source": ["field1", "field2"]
}
  1. 使用过滤代替查询:对于不需要进行相关性评分的条件,使用 filter 而不是 queryfilter 操作通常会利用缓存,查询性能更高。例如,在根据某个固定值过滤文档时:
{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "category": "electronics"
                    }
                }
            ]
        }
    }
}
  1. 优化布尔查询:在使用 bool 查询时,合理安排 mustshouldfiltermust_not 子句。将更严格、过滤效果更好的条件放在前面,这样可以快速减少需要处理的文档数量。例如,如果有两个条件,一个是 term 过滤条件,另一个是 match 全文搜索条件,应将 term 条件放在前面作为 filtermust 子句。
  2. 使用聚合优化:在进行聚合操作时,尽量减少聚合的层级和聚合的文档数量。可以通过 filter 先对数据进行过滤,然后再进行聚合。同时,对于嵌套聚合,合理安排聚合顺序,以减少中间结果集的大小。例如:
{
    "query": {
        "bool": {
            "filter": [
                {
                    "range": {
                        "price": {
                            "gte": 100
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "category_agg": {
            "terms": {
                "field": "category"
            },
            "aggs": {
                "avg_price": {
                    "avg": {
                        "field": "price"
                    }
                }
            }
        }
    }
}
  1. 避免使用通配符查询:通配符查询(如 *?)在大数据量时性能较差,因为它需要对每个文档进行匹配。尽量使用 termmatch 查询代替通配符查询,如果实在需要使用通配符,尽量将通配符放在词尾而不是词首,因为词首通配符查询无法利用倒排索引,性能更低。

其他优化

  1. 集群硬件优化
    • 硬件配置:确保集群节点有足够的内存、CPU 和磁盘 I/O 性能。内存对于 Elasticsearch 非常重要,因为它会缓存索引数据和查询结果。建议为每个节点分配足够的堆内存,但也要注意避免堆内存过大导致垃圾回收问题。CPU 性能影响数据处理速度,磁盘 I/O 性能则影响数据的读写速度,选择高性能的磁盘(如 SSD)可以显著提升性能。
    • 网络优化:保证集群内部网络带宽充足,减少网络延迟和丢包。合理配置网络拓扑,避免网络瓶颈。
  2. 缓存优化
    • 查询结果缓存:利用 Elasticsearch 的查询结果缓存机制,如 fielddata 缓存和 filter 缓存。fielddata 缓存可以加快排序和聚合操作,filter 缓存可以缓存过滤结果,提高重复查询的性能。但要注意缓存的内存管理,避免缓存占用过多内存导致节点性能下降。
    • 索引缓存:合理设置索引的缓存参数,如 index.cache.filter.sizeindex.cache.fielddata.size,以控制缓存的大小和使用方式。根据业务查询模式和数据特点,调整这些参数以达到最佳的缓存效果。