解剖 Elasticsearch 集群 - 之三

本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇。在本篇文章中,我们会讨论 Elasticsearch 如何提供准实时搜索以及如何在搜索相关度计算与延迟间权衡。

在之前的文章中,我们讨论了 Elasticsearch 如何应对分布式系统的一些基本挑战。这里我们主要讨论:

  • Elasticsearch 的准实时
  • 为什么深度分页会很危险?
  • 权衡搜索相关度的计算

准实时搜索(Near real-time search)

Elasticsearch 里的修改不是立刻可见,但它确实提供了一个准实时的搜索引擎。如之前文章提到的,将 Lucene 的修改提交到磁盘是一个代价高昂的操作。为了让提交修改到磁盘的时候文档仍然可供搜索,在内存缓冲与磁盘之间有一个文件系统缓存。内存缓冲每秒刷新(默认)同时包含倒排索引的新段会创建与文件系统缓存中。这个段是开放的并可供搜索。

文件系统缓存有文件句柄,可以打开、读取以及关闭文件,不过它是在内存中的。因为默认刷新的间隔是 1 秒,修改并不是立即可见,尽管如此它还是准实时的。因为 translog 是一条对未持久化到磁盘的所有修改的持久化记录,它对 CRUD 操作的准实时方面也有所帮助。对于每次请求,都会在查看相关的段信息之前,先搜索 translog ,所以客户端可以在准实时状态下访问所有发生的修改。

也可以显式地在每次 Create/Update/Delete 操作后刷新索引,让修改对客户端立刻可见,但我们并不推荐这么做,因为这样会创建很多小段导致搜索的性能下降。在 Elasticsearch 索引里一个分片的所有的段都会被搜索,但是读取所有匹配文档或读取处于深度分页里的文档是很危险的。让我们看看为什么会这样。

为什么在分布式搜索中深度分页是十分危险的?

当搜索匹配 Elasticsearch 中的很多文档时,默认情况下,会返回第一页的内容并包括最前的 10 个结果。搜索 API 有参数 fromsize 指定搜索结果的深度。例如,如果想看排名第 5060 的文档,那么参数值应该是 from=50size=10 。每个分片都会接收到搜索请求,它创建一个大小为 from+size 的优先队列满足自身的搜索结果,然后将结果返回到协调节点。

如果想要看排名从 50,000 到 50,010 的结果,那么每个分片就会需要创建大小为 50,010 的优先队列,协调节点就需要在内存中对 number of shards * 50,010 个结果进行排序。由于硬件资源的限制,这种层次的分页可能不大可能,但是这种深度分页需要非常小心,因为它可以轻而易举地弄垮集群。

可以通过 scroll API 获得所有匹配的文档,这和关系型数据库中游标的的行为很像。在 scroll API 中,排序是被禁用的,只要文档与搜索匹配,分片就会返回结果。

如果有大量文档被读取,对评分结果的排序是个代价昂贵的过程。因为 Elasticsearch 是一个分布式系统,为文档计算搜索相关度评分代价很大。让我们看看如果做权衡。

权衡搜索相关度的计算

Elasticsearch 用 tf-idf 来评价搜索的相关度,由于它分布性的本质,计算全局的 idf(倒排文档频率 - inverse document frequency)是十分昂贵的。相反,每个分片计算一个局部的 idf 并为结果分配一个相关度评分,然后只返回改分片内的文档。相似地,所有分片返回结果以及本地 idf 计算出的相关度评分,协调节点会对所有结果进行排序并返回处于最前的文档。这在大多数情况下都是有效的,除非索引根据关键字进行了调整或单个分片没有足够的数据能代表集群的全局分布。

例如,如果搜索 “insight” 这个词,分片内大多数文档都包含词项 “insight” ,与查询匹配的文档可能不会在每个分片中进行正确排名,因为局域 idf 值的变化会很大,搜索结果可能不会那么相关。类似地,如果没有足够的数据,局域 idf 值也会变化很大,搜索结果的相关性也不如期望的那样。真实世界的数据往往是充足的,局域 idf 值会趋同搜索结果的评分也会是公平的。

也有一些方式可以规避局域 idf 评分的影响,但并不推荐在生产环境使用。

  • 一种方式是只为索引使用一个分片,这样局域的 idf 就是全局的 idf ,但这牺牲了并行性和扩展,对巨量索引也不切实际。
  • 另外一种方式是为搜索请求使用参数 dfs_query_then_search (dfs = distributed frequency search) ,它会先为所有分片计算局域 idf ,然后将这些局域的 idf 值为整个索引计算出一个全局的 idf ,返回结果的相关度评分是根据这个全局 idf 计算出来的。不推荐在生产环境使用它,足够的数据就可以保证词频能很好的分布。

在之前的一些文章中,我们查看了 Elasticsearch 的一些基本原理,这对理解和使用它非常重要。在后续的文章中,我会介绍如何使用 Apache Spark 将数据索引到 Elasticsearch。

参考

参考来源:

Anatomy of an Elasticsearch Cluster: Part III

结束

解剖 Elasticsearch 集群 - 之三的更多相关文章

  1. 解剖 Elasticsearch 集群 - 之二

    解剖 Elasticsearch 集群 - 之二 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论 Elasticsearch 是如何处理 3C ...

  2. 解剖 Elasticsearch 集群 - 之一

    解剖 Elasticsearch 集群 - 之一 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论底层的存储模型以及 CRUD(创建.读取.更新 ...

  3. Ubuntu 14.04中Elasticsearch集群配置

    Ubuntu 14.04中Elasticsearch集群配置 前言:本文可用于elasticsearch集群搭建参考.细分为elasticsearch.yml配置和系统配置 达到的目的:各台机器配置成 ...

  4. elasticsearch 集群

    elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他们搭建成为一个集群 基本配置 每个节点都要进行这样的配置: cluster.name: ba ...

  5. 我的ElasticSearch集群部署总结--大数据搜索引擎你不得不知

    摘要:世上有三类书籍:1.介绍知识,2.阐述理论,3.工具书:世间也存在两类知识:1.技术,2.思想.以下是我在部署ElasticSearch集群时的经验总结,它们大体属于第一类知识“techknow ...

  6. Elasticsearch集群中处理大型日志流的几个常用概念

    之前对于CDN的日志处理模型是从logstash agent==>>redis==>>logstash index==>>elasticsearch==>&g ...

  7. elasticsearch 集群配置

    2015-10-10 09:56 by 轩脉刃, 999 阅读, 1 评论, 收藏, 编辑 elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他 ...

  8. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(5)

    数据操作与REST API(Data manipulation with REST API) ElasticSearch REST API可用于各种任务.多亏了它,我们可以管理索引,更改实例参数,检查 ...

  9. Elasticsearch集群搭建

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

随机推荐

  1. CentOS 在同一窗口打开文件夹

    1.打开一个文件夹 2.编辑 - 首选项 - 行为,勾选“总是在浏览器窗口打开”,点击关闭.

  2. LINQ To SQL && Lambda 使用方法小结 (转)

    1. 查询Student表中的所有记录的Sname.Ssex和Class列.select sname,ssex,class from studentLinq: from s in Students   ...

  3. memory runs at single channel问题解决

    memory runs at single channel 解决方案:开机后按DEL ,然后进入BIOS 选择第一项,回车! advanced下面的有个momori什么什么的,选择disable. m ...

  4. P3P解决cookie存取的跨域问题

    最近在做一个流量统计的东西的时候,偶然发现IE在对iframe里面的页面写Cookie的时候有一些安全限制,导致读取Cookie不成功,找了好长时间的解决办法,重要找到如下的办法: 1.页面里的COO ...

  5. A. Round House

    A. Round House time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  6. IFieldEdit Interface 接口

    Description The IFieldEdit interface is used when creating new fields. You should not use it to modi ...

  7. webfont 字体

    http://www.phpdl.com/demo/webfont/index.html 淘宝web font字体,开源. 自定义字体,网站可以用服务端字体. 一般来说,只能用客户端字体.格式不同,为 ...

  8. 向datagridview 添加行

    datagridview 已经绑定数据源且控件的AllowUserToAddRows设置为false时. ((DataTable)dataGridView1.DataSource).Rows.Add( ...

  9. 获取当前路径 ${pageContext.request.contextPath}

    ${pageContext.request.contextPath}

  10. 一道关于 precision、recall 和 threshold关系的机器学习题

    Suppose you have trained a logistic regression classifier which is outputing hθ(x). Currently, you p ...