面试题答案
一键面试索引设计优化
- 字段映射优化:
- 原理:根据商品数据的特点,合理设置字段类型。例如,对于价格字段,选择合适的数值类型(如
float
或double
),避免使用text
类型,因为text
类型默认会进行分词,不适合数值的精确检索。对于商品名称等文本字段,根据业务需求选择合适的分词器,如ik_max_word
适合中文细粒度分词,能提高搜索的召回率。 - 策略:对商品描述等长文本字段,可以考虑设置
norms
为false
,以减少存储开销,因为norms
主要用于计算相关性分数,在某些场景下可能不需要。同时,对于一些不需要进行搜索,但需要展示的字段(如商品图片链接),可以设置为doc_values
为false
,减少磁盘占用。
- 原理:根据商品数据的特点,合理设置字段类型。例如,对于价格字段,选择合适的数值类型(如
- 索引分片与副本优化:
- 原理:分片是将索引数据分布到不同的节点上,提高数据的并行处理能力和存储能力。副本是对分片的复制,用于提高系统的可用性和读性能。
- 策略:根据预估的商品数据量和集群节点数量,合理设置分片数。一般原则是每个分片大小控制在 10 - 50GB 为宜。例如,如果预估商品数据总量为 1TB,且集群有 10 个节点,可设置 20 - 50 个分片。副本数根据读请求的并发量来设置,高并发读场景下,可以适当增加副本数,如设置为 2 - 3 个副本,以提高读性能,但同时要注意副本数过多会增加写操作的负担和存储成本。
写操作优化
- 批量处理:
- 原理:将多个写操作合并为一个批量请求,减少网络开销和 ES 内部处理的压力。ES 在处理批量请求时,会将多个操作作为一个整体进行处理,减少了单个请求的资源开销。
- 策略:在商品数据实时更新时,尽量将多个商品的更新操作组合成一个批量请求发送到 ES 集群。例如,可以设置一个阈值,当积累到一定数量(如 100 条)的商品更新时,发起一次批量写请求。
- 异步写入:
- 原理:采用异步方式进行写操作,将写请求放入队列中,由专门的线程或进程进行处理,这样可以避免写操作阻塞应用程序的主线程,提高应用程序的响应速度。
- 策略:在应用层使用消息队列(如 Kafka)来接收商品数据的更新请求,ES 从消息队列中消费这些请求并进行写入操作。这样可以解耦写操作与业务逻辑,提高系统的整体吞吐量。
读操作优化
- 缓存机制:
- 原理:在 ES 集群前端设置缓存,如 Redis。对于一些高频的搜索请求,先从缓存中查找结果,如果命中则直接返回,避免对 ES 集群的重复查询,减轻 ES 的读压力。
- 策略:可以根据搜索关键词、搜索条件等生成缓存的 key,将 ES 返回的搜索结果缓存到 Redis 中。设置合适的缓存过期时间,对于时效性要求高的商品搜索结果,可以设置较短的过期时间(如几分钟),对于时效性要求相对较低的,可以设置较长的过期时间(如几小时)。
- 搜索请求优化:
- 原理:优化用户的搜索请求,减少不必要的查询复杂度,提高 ES 搜索效率。
- 策略:对用户输入的搜索关键词进行预处理,如去除停用词、进行同义词扩展等。在构建查询语句时,尽量使用简单高效的查询方式,例如对于精确匹配的字段,使用
term
查询;对于模糊匹配的文本字段,使用match
查询并合理设置参数。同时,可以根据业务需求设置查询的timeout
,避免长时间的查询等待。
集群配置优化
- 节点角色优化:
- 原理:在 ES 主从模式下,合理分配节点角色,不同角色的节点承担不同的任务,提高集群的整体性能。
- 策略:将集群中的节点分为主节点、数据节点和协调节点。主节点主要负责集群的管理工作,如创建、删除索引,分配分片等,数量不宜过多,一般 3 - 5 个为宜。数据节点负责存储和处理数据,根据数据量和性能需求合理设置数量。协调节点负责接收用户的请求,并将请求路由到相应的数据节点,然后将结果汇总返回给用户,可以适当增加协调节点的数量来处理高并发的读请求。
- 资源分配优化:
- 原理:根据节点的硬件资源(如 CPU、内存、磁盘等),合理分配 ES 进程的资源,以充分发挥节点的性能。
- 策略:对于数据节点,由于需要大量的内存来缓存数据和进行查询处理,应分配较多的堆内存,一般建议堆内存设置为节点物理内存的 50%,且不超过 32GB。同时,确保磁盘有足够的空间来存储数据,并且使用高性能的磁盘(如 SSD)以提高 I/O 性能。对于主节点和协调节点,根据其任务特点,合理分配 CPU 和内存资源,保证其稳定运行。