转载: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. 从UEditor内容中获取指定节点值(转)

    今天吐槽一下百度的富文本编辑器UEditor,这种富文本编辑器极大地方便我们上传文件,开发人员无需编写任何上传代码,只需配置几个路径即可.但高度集成的东西有时也显得笨重,灵活度不高.比如:编辑器中我既 ...

  2. Shell获取某目录下所有文件夹的名称

    查看目录下面的所有文件: #!/bin/bash cd /目标目录 for file in $(ls *) do echo $file done 延伸的方法,查看目录下面的所有目录 #!/bin/ba ...

  3. Jquery计算时间戳之间的差值,可返回年,月,日,小时等

    /** * 计算时间戳之间的差值 * @param startTime 开始时间戳 * @param endTime 结束时间戳 * @param type 返回指定类型差值(year, month, ...

  4. ceph rgw multisite基本用法

    Realm: Zonegroup: 理解为数据中心,由一个或多个Zone组成,每个Realm有且仅有 一个Master Zonegroup,用于处理系统变更,其他的称为Slave Zonegroup, ...

  5. 【C#】C#中的属性与字段

    目录结构: contents structure [+] 属性和字段的区别 无参属性 自动实现的属性 对象和集合初始化器 匿名类型 System.Tuple类型 有参属性 属性的可访问性 在这篇文章中 ...

  6. [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]

    我要做回自己--Aaronyang的博客(www.ayjs.net) 博客摘要: Virtualizing虚拟化DEMO 和 大数据加载的思路及相关知识 WPF数据提供者的使用ObjectDataPr ...

  7. 手动释放和收缩tempdb

    USE [tempdb] GO DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS DBCC FREESYSTEMCACHE ('ALL') DBCC FREESESSI ...

  8. React Native库版本升级与降级

    迄今为止React Native获得了超过48K的star,最新版本0.44,已经趋于稳定.(官网地址:https://github.com/facebook/react-native).随着Reac ...

  9. MUI中等待框的H5实现

    MUI没有内置的那个弹出转圈圈的那个等待框,那个nativeui.showwaiting是只能用于app中的,不能用在H5网页中的,网上找了下,找到个别人已经写好的,自己 测试了下没问题,先记下来 @ ...

  10. Linux install svn server

    ref: http://blog.csdn.net/pingnanlee/article/details/8812520 1. yum -y install subversion 2. svnadmi ...