Elasticsearch关键术语 系列博文 目的只用来了解概念 ; 其中 涉及到的配置和使用 是为了方便日后使用时查询的
分布式搜索
分布式搜索的运行机制
第一阶段 Query
例如 3个节点的es集群有3个主分片 1个副本 节点收到请求后 会以coordinating node的身份 在6个主副分片中随机选择3个分片 发送查询请求
被选中的分片执行查询 进行排序 然后每个分片都会返回from+size个排序后的文档id和排序值 给coordinating节点
第二阶段 Fetch
coordinating node会将query阶段 从每个分片获取的排序后的文档id列表 重新排序 选取from到from+size个的文档的id
以multi get请求的方式 到响应的分片获取详细的文档数据
引发的问题及解决
相关性算分不准
问题
每个分片都基于自己的分片上的数据进行相关度计算 会导致打分偏离 特别是数据量很少时 相关性算分在分片之间是相互独立的 如果主分片数越多 相关性算分会越不准
解决
-
方式一 调节主分片数 (推荐)
-
配置
-
数据量不大时 将主分片数设置为1
-
数据量大时 保证文档均匀分散在各个分片上 就不会出现算分偏差
-
-
-
方式二 URL中指定参数 (不用)
-
原理
- 到每个分片把各分片的词频和文档频率进行搜集 然后完整的进行一个相关性算分 耗费CPU和内存 性能低
-
配置
- 搜索的URL中添加参数 “_search?search_type=dfs_query_then_fetch”
-
深度分页的性能
问题
因为每个分片上需要查的文档个数 = from + size 所以最终协调节点需要处理number_of_shard*(from+size)个文档个数 深度分页就是痛点了
示例 : 当一个查询 from=990 size=10 ES会在每个分片上都先取1000个文档 然后通过coordinating node聚合所有结果 最后再通过排序选取前1000个文档 展示990到1000这10条数据 页数越深 占用内存越多
解决
- 搜索语句使用 “search_after”:[13,“xsdafvwrevwerbvtwer”] 避免深度分页性能问题
- 作用
- 实时获取下一页文档信息 不能指定from 只能往下翻
- 原理
- 通过唯一排序值定位
- 作用
ES默认限定到10000个文档 想查询10001会报错
解决
- settings中设置
- index.max_result_window
参考
阮一名资料
官方文档
百度