面试题答案
一键面试索引结构优化
- 文档设计:
- 对于不同用户角色所需的信息,尽量在文档结构设计时进行合理布局。例如,将普通用户所需的摘要信息(标题、简介等)放在容易提取的顶层字段,避免深度嵌套,这样在普通用户查询时可以快速获取这些信息,减少解析成本。
- 对于管理员所需的完整详细信息,可按原复杂嵌套结构保留,但同时可以考虑增加一些冗余字段,将部分常用的详细信息提升到顶层,以便快速查询。
- 字段映射:
- 合理设置字段的数据类型,例如对于字符串类型字段,如果不需要进行全文搜索,可设置为
keyword
类型,这样能提高查询效率。 - 对于日期等特殊类型字段,确保映射正确,以便高效进行范围查询等操作。
- 合理设置字段的数据类型,例如对于字符串类型字段,如果不需要进行全文搜索,可设置为
- 索引分片与副本:
- 根据数据量和服务器资源合理分配索引分片数,分片数过多或过少都会影响性能。一般可根据经验公式和实际测试来确定,例如每个分片大小控制在 10 - 50GB 左右。
- 设置适当的副本数,副本主要用于提高高可用性和读性能,但过多副本会占用更多资源,可根据实际读请求压力来调整,一般设置 1 - 3 个副本。
API 调用优化
- 查询 DSL 优化:
- 对于管理员查询,由于需要返回完整信息,查询语句应尽量精准,可利用 ElasticSearch 的
filter
子句等,在不进行评分的情况下快速筛选数据,提高查询速度。例如:
{ "query": { "bool": { "filter": [ { "term": { "user_role": "admin" } }, // 其他查询条件 ] } } }
- 对于普通用户查询,只查询所需的摘要信息字段,使用
_source
参数指定返回字段,减少数据传输量。例如:
{ "query": { "bool": { "filter": [ { "term": { "user_role": "normal_user" } }, // 其他查询条件 ] } }, "_source": ["title", "intro"] }
- 对于管理员查询,由于需要返回完整信息,查询语句应尽量精准,可利用 ElasticSearch 的
- 批量查询:
- 如果有多个查询请求,可以合并为批量查询,减少网络开销。ElasticSearch 提供了
mget
等批量查询 API。例如,对于一批用户的查询请求,可以构建如下请求:
{ "docs": [ { "_index": "your_index", "_id": "doc_id_1" }, { "_index": "your_index", "_id": "doc_id_2" } ] }
- 如果有多个查询请求,可以合并为批量查询,减少网络开销。ElasticSearch 提供了
缓存策略
- 客户端缓存:
- 在客户端(如 Web 应用前端)对经常查询的结果进行缓存。可以使用浏览器的
localStorage
或sessionStorage
缓存普通用户的查询结果,有效期可根据数据更新频率设置。例如,如果数据一天更新一次,缓存有效期可设置为一天。 - 对于管理员用户,由于数据可能更敏感且更新频繁,可采用较短的缓存有效期,如一小时。
- 在客户端(如 Web 应用前端)对经常查询的结果进行缓存。可以使用浏览器的
- 服务器端缓存:
- 在应用服务器层设置缓存,如使用 Redis。对于相同查询条件的结果进行缓存,当再次收到相同查询时,直接从缓存中返回结果,减少对 ElasticSearch 的查询压力。
- 可以根据用户角色和查询条件生成唯一的缓存键,例如
user_role:admin_query:query_string
。 - 设置合理的缓存淘汰策略,如 LRU(最近最少使用),确保缓存空间的有效利用。
- ElasticSearch 内部缓存:
- ElasticSearch 本身有查询缓存和字段数据缓存等。合理配置这些缓存参数,例如调整查询缓存的大小,根据实际查询模式优化缓存命中率。对于经常查询的索引和字段,适当增大字段数据缓存的大小。
整体架构设计
- 用户认证与鉴权:
- 在应用入口处进行用户认证和鉴权,确定用户角色。可以使用 JWT(JSON Web Token)等技术,在用户登录时生成包含用户角色等信息的令牌,后续请求携带该令牌,应用服务器验证令牌并获取用户角色。
- 请求分发:
- 根据用户角色将查询请求分发到不同的处理逻辑。例如,对于管理员请求,直接调用获取完整文档信息的查询逻辑;对于普通用户请求,调用获取摘要信息的查询逻辑。
- 性能监控与调优:
- 部署性能监控工具,如 ElasticSearch 的监控插件(如 Marvel 或 X - Pack 中的监控功能),实时监控索引性能指标(如查询耗时、分片负载等)。
- 根据监控数据定期进行性能调优,如调整索引结构、缓存参数等,确保系统在高并发环境下持续保持良好性能。