面试题答案
一键面试索引设计方面
- 优化字段映射
- 方法:根据数据类型准确设置字段映射。例如,对于不需要进行全文搜索的字段,设置为
keyword
类型,而不是默认的text
类型。对于数值类型,使用合适的数值类型,如long
、integer
等。 - 原理:
keyword
类型的字段不会进行分词,存储和查询时更高效,减少了不必要的分词计算开销。合适的数值类型能更有效地利用存储空间,提升数值范围查询等操作的性能。
- 方法:根据数据类型准确设置字段映射。例如,对于不需要进行全文搜索的字段,设置为
- 使用合适的分词器
- 方法:根据业务需求选择合适的分词器。比如对于中文文本,使用
ik_max_word
等中文分词器。如果是英文,根据具体情况选择standard
、english
等分词器。 - 原理:合适的分词器能将文本更合理地切分成词项,使得索引中的词项更符合搜索需求,提高搜索命中率,减少无效的匹配尝试,从而提升搜索性能。
- 方法:根据业务需求选择合适的分词器。比如对于中文文本,使用
- 设置合理的索引分片和副本
- 方法:根据数据量和硬件资源,合理设置索引的分片数和副本数。一般来说,初始时可以根据预估数据量和节点数来确定分片数,如每个分片控制在几十GB到100GB左右。副本数根据对高可用和读性能的需求设置,通常1 - 2个副本。
- 原理:合适的分片数可以将数据均匀分布在集群节点上,避免单个节点数据量过大影响性能。副本可以分担读请求,提升整体的读性能,同时保证高可用性。
查询优化方面
- 使用Filter查询
- 方法:对于不需要计算相关性分数,只用于筛选数据的条件,使用
filter
查询。例如,根据时间范围、固定枚举值等条件筛选数据。 - 原理:
filter
查询不计算相关性分数,会利用缓存,查询速度更快。缓存可以避免重复执行相同的筛选条件查询,提升查询性能。
- 方法:对于不需要计算相关性分数,只用于筛选数据的条件,使用
- 批量查询
- 方法:将多个相似的查询合并为一个批量查询。例如,在需要获取多个文档的场景下,使用
mget
API一次性获取多个文档,而不是多次单个查询。 - 原理:减少网络开销,一次请求代替多次请求,同时集群可以更高效地处理批量请求,提升整体的查询效率。
- 方法:将多个相似的查询合并为一个批量查询。例如,在需要获取多个文档的场景下,使用
- 使用Query DSL优化
- 方法:准确使用
bool
查询的must
、should
、must_not
等子句来构建复杂查询。例如,将必须满足的条件放在must
子句,可选条件放在should
子句。 - 原理:合理的
Query DSL
结构能让ElasticSearch更准确地理解查询意图,优化查询执行计划,提高查询性能。
- 方法:准确使用
集群配置方面
- 增加节点资源
- 方法:给集群中的节点增加更多的内存、CPU等硬件资源,或者增加节点数量。
- 原理:更多的内存可以容纳更多的索引数据在内存中,减少磁盘I/O,提升查询速度。更多的CPU核心可以并行处理更多的查询任务。增加节点数量可以分担数据存储和查询负载,提升整体性能。
- 优化集群网络配置
- 方法:确保集群内部网络带宽充足,网络延迟低。配置合理的网络拓扑,如使用高速交换机等。
- 原理:快速的网络可以加快节点之间的数据传输,包括数据同步、查询结果返回等,减少网络等待时间,提升搜索API的响应速度。
- 调整ElasticSearch配置参数
- 方法:例如调整
indices.memory.index_buffer_size
参数,控制索引缓存的大小,根据节点内存情况合理设置该值。还可以调整thread_pool.search.size
参数,设置搜索线程池的大小。 - 原理:合适的索引缓存大小可以更好地缓存索引数据,减少磁盘读取。合理的搜索线程池大小可以控制并行处理的搜索任务数量,避免资源过度竞争,提升搜索性能。
- 方法:例如调整