ESES分布式搜索的运行机制ES有两个search_type,即搜索类型:query_then_fetch(default)dfs_query_then_fetchquery_then_fetch用户发起搜索,请求到集群中的某个节点。查询将发送到所有相关分片。每个分片独立执行查询以搜索文档、排序和分页等,并使用分片本身的LocalTerm/Document频率进行评分。分片查询结果(仅元数据如_id和_score)返回给请求节点。请求节点汇总所有分片的查询结果,然后根据分值排序分页,最后选择搜索结果文档(仅元数据)。根据元数据,到对应的分片中拉取存储在磁盘上的文档的详细数据。获取详细的文档数据,组成搜索结果,并将结果返回给用户。缺点:由于每个分片独立使用自己的而不是全局的Term/Document频率进行相关性评分,当数据分布不均匀时,可能会造成评分偏差,从而影响最终搜索结果的相关性。dfs_query_then_fetchdfs_query_then_fetch的工作方式与query_then_fetch非常相似,但有两个区别。用户向集群中的节点发起搜索和请求。预查询每个分片以获得全局全局术语/文档频率。查询将发送到所有相关分片。每个分片独立执行查询以搜索文档、排序和分页等,并使用分片本身的全局词/文档频率进行评分。分片查询结果(仅元数据如_id和_score)返回给请求节点。请求节点汇总所有分片的查询结果,然后根据分值排序分页,最后选择搜索结果文档(仅元数据)。根据元数据,到对应的分片中拉取存储在磁盘上的文档的详细数据。获取详细的文档数据,组成搜索结果,并将结果返回给用户。缺点:太耗资源,一般不推荐。经验虽然ES有两种搜索类型,但一般使用默认的query_then_fetch。当数据量不够大时(比如搜索类数据20GB,日志类数据20-50GB),建议设置分片primaryshard。如果你只设置一个primaryshard,你会发现搜索省了很多东西。当不需要文档数据时,使用_source:false来避免请求节点到非原生分片的网络耗时和读取磁盘文件的耗时。使用from+size分页时,假设只需要前10k条数据的后十条,那么每个shard也会取10k条数据。如果你的索引有5个primaryshard,那么在汇总10k=50k条数据的时候会有5*,这50k条数据在内存中排序最后分页,所以深分页也比较耗资源。
