转载: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提供了fromsize参数,用于指定对于匹配搜索的全部文档,要返回多深的结果。举例来说,如果我们想看到匹配搜索的文档中,排名为5060之间的文档,可以设置from=50size=10。当每个分片接收到这个搜索请求后,各自会创建一个容量为from+size的优先队列来存储该分片上的搜索结果,然后将结果返回给协调节点。

如果我们想看到排名为50,00050,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集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道的更多相关文章

  1. 剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作

    剖析Elasticsearch集群系列涵盖了当今最流行的分布式搜索引擎Elasticsearch的底层架构和原型实例. 本文是这个系列的第一篇,在本文中,我们将讨论的Elasticsearch的底层存 ...

  2. 剖析Elasticsearch集群系列之一:Elasticsearch的存储模型和读写操作

    转载:http://www.infoq.com/cn/articles/analysis-of-elasticsearch-cluster-part01 1.辨析Elasticsearch的索引与Lu ...

  3. 剖析Elasticsearch集群系列之二:分布式的三个C、translog和Lucene段

    转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part02 共识——裂脑问题及法定票数的重要性 共识是 ...

  4. mongo 3.4分片集群系列之三:搭建分片集群--哈希分片 + 安全

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  5. Elasticsearch集群搭建

    现有两部机器:192.168.31.86,192.168.31.87   参考以往博文对Elasticsearch进行配置完成:http://www.cnblogs.com/zhongshengzhe ...

  6. mongo 3.4分片集群系列之八:分片管理

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  7. mongo 3.4分片集群系列之七:配置数据库管理

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  8. mongo 3.4分片集群系列之六:详解配置数据库

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  9. mongo 3.4分片集群系列之五:详解平衡器

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

随机推荐

  1. linux tomcat 绑定域名

    1.解析域名到对应的服务器ip 2.找到tomcat安装路径进入/conf 3.vi server.xml 4.修改<Connector port="8080" protoc ...

  2. GraphQL入门1

    1. 资源: 主站: https://graphql.org/ 中文站: http://graphql.cn 入门视频: https://graphql.org/blog/rest-api-graph ...

  3. [Java] LinkedHashMap 源码简要分析

    特点 * 各个元素不仅仅按照HashMap的结构存储,而且每个元素包含了before/after指针,通过一个头元素header,形成一个双向循环链表.使用循环链表,保存了元素插入的顺序. * 可设置 ...

  4. 转发:查看centos中的用户和用户组

    1.用户列表文件:/etc/passwd/ 2.用户组列表文件:/etc/group 3.查看系统中有哪些用户: cut -d : -f 1 /etc/passwd 4.查看可以登录系统的用户: ca ...

  5. 基于CentOS 7 搭建 GitLab

    系统要求:CentOS 7.2 64 位操作系统 更新软件包 yum update -y 安装和启动 sshd 安装 sshd: yum install -y curl policycoreutils ...

  6. Spark2.3 HA集群的分布式安装

    一.下载Spark安装包 1.从官网下载 http://spark.apache.org/downloads.html 2.从微软的镜像站下载 http://mirrors.hust.edu.cn/a ...

  7. SNF快速开发平台MVC-名片管理(实际名片样式)

    名片管理实际的做的意义在于演示应用,在这里使用的技术有排序控件,查询条件.自由样式瀑布流式分页等技术. 下面是自由样式效果图: 下面表格样式效果图: 具体操作: 新增名片 在新增时可以上传图像进行裁剪 ...

  8. 通过MTK迁移Mysql到EDB实战指南

    1.1 迁移准备 下图是Migration toolkit(MTK)可使用的迁移功能 1 查看一下迁移源数据库testdb信息.共三张表 watermark/2/text/aHR0cDovL2Jsb2 ...

  9. python列表中元素插入位置总结

    要完成的操作是把一个列表里的元素通过for循环添加到另外一个列表里,但是通过insert()方法添加到另外一个列表后却发现元素的位置与原始列表的颠倒了.如以下实例: li1 = ['] li2 = [ ...

  10. 为什么要用 Node.js

    每日一篇优秀博文 2017年10月10日 周二 为什么要用 Node.js 这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正. Node.js 是什么 传统意义上 ...