剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道
转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03
近实时搜索
虽然Elasticsearch中的变更不能立即可见,它还是提供了一个近实时的搜索引擎。如前一篇中所述,提交Lucene的变更到磁盘是一个代价昂贵的操作。为了避免在文档对查询依然有效的时候,提交变更到磁盘,Elasticsearch在内存缓冲和磁盘之间提供了一个文件系统缓存。内存缓存(默认情况下)每1秒刷新一次,在文件系统缓存中使用倒排索引创建一个新的段。这个段是开放的并对搜索有效。
文件系统缓存可以拥有文件句柄,文件可以是开放的、可读的或者是关闭的,但是它存在于内存之中。因为刷新间隔默认是1秒,变更不能立即可见,所以说是近实时的。因为translog是尚未落盘的变更持久化记录,它能有助于CRUD操作方面的近实时性。对于每次请求来说,在查找相关段之前,任何最近的变更都能从translog搜索到,因此客户端可以访问到所有的近实时变更。
你可以在创建/更新/删除操作后显式地刷新索引,使变更立即可见,但我并不推荐你这样做,因为这样会创建出来非常多的小segment而影响搜索性能。对于每次搜索请求来说,给定Elasticsearch索引分片中的全部Lucene段都会被搜索到,但是,对于Elasticsearch来说,获取全部匹配的文档或者很深结果页的文档是有害的。让我们来一起看看为什么是这样。
为什么深层分页在分布式搜索中是有害的?
当我们的一次搜索请求在Elasticsearch中匹配了很多的文档,默认情况下,返回的第一页只包含前10条结果。search API提供了from和size参数,用于指定对于匹配搜索的全部文档,要返回多深的结果。举例来说,如果我们想看到匹配搜索的文档中,排名为50到60之间的文档,可以设置from=50,size=10。当每个分片接收到这个搜索请求后,各自会创建一个容量为from+size的优先队列来存储该分片上的搜索结果,然后将结果返回给协调节点。

如果我们想看到排名为50,000到50,010的结果,那么每个分片要创建一个容量为50,010的优先队列来存储结果,而协调节点要在内存中对数量为shards * 50,010的结果进行排序。这个级别的分页有可能得到结果,也有可以无法实现,这取决于我们的硬件资源,但是这足以说明,我们得非常小心地使用深分页,因为这非常容易使我们的集群崩溃。
一种获取全部匹配结果文档的可行性方案是使用scroll API,它的角色更像关系数据库中的游标。使用scroll API无法进行排序,每个分片只要有匹配搜索的文档,就会持续发送结果给协调节点。
获取大量文档的时候,对结果进行得分排序会非常昂贵。并且由于Elasticsearch是分布式系统,为每个文档计算搜索相关性得分是非常昂贵的。现在,让我们一起看看计算搜索相关性的诸多权衡中的一种。
计算搜索相关性中的权衡
Elasticsearch使用tf-idf来计算搜索相关性。由于其分布式的性质,计算全局的idf(inverse document frequency,逆文档频率)非常昂贵。反之可以这样,每个分片计算本地的idf并将相关性得分分配给结果文档,返回的结果只关乎该分片上的文档。同样地,所有分片使用本地idf计算的相关性得分,返回结果文档,协调节点对所有结果排序并返回前几条。这样做在大多数情况下是没有问题的,除非索引的关键字词项有倾斜或者单个分片上没有代表全局的足够数据。
比如说,如果我们搜索“insight”这个词,但包含"insight"这个词项的大多数文档都存放在一个分片上,这样以来匹配查询的文档将不能公平地在每个分片上进行排序,因为每个分片上的本地idf的值非常不同,得到的搜索结果可能不会非常相关。同样地,如果没有足够的数据,那么对于某些搜索而言,本地idf的值可能大有不同,结果也会不如预期相关。在有足够数据的真实场景中,本地idf值一般会趋于均等,搜索结果是相关的,因为文档得到了公平的得分。
这里有2种应对本地idf得分的办法,但都不建议真正在生产环境中使用。
- 一种办法是一索引一分片,本地idf即是全局idf,但这没有为并行计算/水平伸缩留有余地,对于大型索引并不实用。
- 另一种办法是在搜索请求中使用dfs_query_then_search (dfs = distributed frequency search,分布式频率搜索) 参数,这样以来,会首先计算每个分片的本地idf,然后综合这些本地idf的值来计算整个索引的全局idf值,最后使用全局idf计算相关性得分来返回结果。这种方式不为生产环境推荐,因为有足够的数据确保词项频率分布均匀。
在本系列的过去几篇中,我们回顾了一些Elasticsearch的基本原则,对于我们理解并上手Elasticsearch,这些内容非常重要。在接下来的一篇中,我将使用Apache Spark来研究Elasticsearch中的索引数据。
剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道的更多相关文章
- 剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作
剖析Elasticsearch集群系列涵盖了当今最流行的分布式搜索引擎Elasticsearch的底层架构和原型实例. 本文是这个系列的第一篇,在本文中,我们将讨论的Elasticsearch的底层存 ...
- 剖析Elasticsearch集群系列之一:Elasticsearch的存储模型和读写操作
转载:http://www.infoq.com/cn/articles/analysis-of-elasticsearch-cluster-part01 1.辨析Elasticsearch的索引与Lu ...
- 剖析Elasticsearch集群系列之二:分布式的三个C、translog和Lucene段
转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part02 共识——裂脑问题及法定票数的重要性 共识是 ...
- mongo 3.4分片集群系列之三:搭建分片集群--哈希分片 + 安全
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
- Elasticsearch集群搭建
现有两部机器:192.168.31.86,192.168.31.87 参考以往博文对Elasticsearch进行配置完成:http://www.cnblogs.com/zhongshengzhe ...
- mongo 3.4分片集群系列之八:分片管理
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
- mongo 3.4分片集群系列之七:配置数据库管理
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
- mongo 3.4分片集群系列之六:详解配置数据库
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
- mongo 3.4分片集群系列之五:详解平衡器
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
随机推荐
- GeoHash原理和可视化显示
最近在做附近定位功能的产品,geohash是一个非常不错的实现方式.查询资料,发现阿里的这篇文章讲解的很好.但文中并没有给出geohash显示的工具.无奈,也没有查到类似的.只好自己简单显示一下,方便 ...
- Spark2.3(三十六):根据appName验证某个app是否在运行
具体脚本 #/bin/sh #LANG=zh_CN.utf8 #export LANG export SPARK_KAFKA_VERSION=0.10 export LANG=zh_CN.UTF- # ...
- 原创:vsphere概念深入系列三:vSphere命令行管理
假设无法近距离接触物理主机,只能远程命令行管理,. 以下命令行可以起到点作用. 首先需要安装vSphere CLI工具. 启动后界面: 1.查看datastore内容 所有命令行工具都可以加上-ser ...
- 查看最新的Google地址
nslookup www.google.com 8.8.8.8
- Nginx负载均衡权重,ip_hash
nginx为后端web服务器(apache,nginx,tomcat,weblogic)等做反向代理 几台后端web服务器需要考虑文件共享,数据库共享,session共享问题.文件共享可以使用nfs, ...
- 如何给Elasticsearch安装中文分词器IK
安装Elasticsearch安装中文分词器IK的步骤: 1. 停止elasticsearch 2.2的服务 2. 在以下地址下载对应的elasticsearch-analysis-ik插件安装包(版 ...
- springboot集成redis缓存
1.pom.xml增加redis缓存起步依赖(spring-boot-starter-parent包含许多starter版本) <dependency> <groupId>or ...
- kubernetes中port、target port、node port的对比分析,以及kube-proxy代理
转:http://blog.csdn.net/xinghun_4/article/details/50492041 容器网络实例 服务中的3个端口设置 这几个port的概念很容易混淆,比如创建如下se ...
- netty实现多个handler顺序调用
在netty中,一次数据交互,可以由多个handler去处理,例如 handler1 和 handler2,那么,在前面那个handler的 messageReceived 的最后要加上 ctx.se ...
- Atitit.每周计划日程表 流程表v3
Atitit.每周计划日程表 流程表 每周趋势总结 新特性聚合 最佳实践聚合. 上周总结 本度计划 检查于推进年度计划月度计划里程碑 检查于推进季度计划月度计划里程碑 上周Todo汇总结转.. 待报 ...