解剖 Elasticsearch 集群 - 之三
解剖 Elasticsearch 集群 - 之三
本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇。在本篇文章中,我们会讨论 Elasticsearch 如何提供准实时搜索以及如何在搜索相关度计算与延迟间权衡。
在之前的文章中,我们讨论了 Elasticsearch 如何应对分布式系统的一些基本挑战。这里我们主要讨论:
- Elasticsearch 的准实时
- 为什么深度分页会很危险?
- 权衡搜索相关度的计算
准实时搜索(Near real-time search)
Elasticsearch 里的修改不是立刻可见,但它确实提供了一个准实时的搜索引擎。如之前文章提到的,将 Lucene 的修改提交到磁盘是一个代价高昂的操作。为了让提交修改到磁盘的时候文档仍然可供搜索,在内存缓冲与磁盘之间有一个文件系统缓存。内存缓冲每秒刷新(默认)同时包含倒排索引的新段会创建与文件系统缓存中。这个段是开放的并可供搜索。
文件系统缓存有文件句柄,可以打开、读取以及关闭文件,不过它是在内存中的。因为默认刷新的间隔是 1 秒,修改并不是立即可见,尽管如此它还是准实时的。因为 translog 是一条对未持久化到磁盘的所有修改的持久化记录,它对 CRUD 操作的准实时方面也有所帮助。对于每次请求,都会在查看相关的段信息之前,先搜索 translog ,所以客户端可以在准实时状态下访问所有发生的修改。
也可以显式地在每次 Create/Update/Delete 操作后刷新索引,让修改对客户端立刻可见,但我们并不推荐这么做,因为这样会创建很多小段导致搜索的性能下降。在 Elasticsearch 索引里一个分片的所有的段都会被搜索,但是读取所有匹配文档或读取处于深度分页里的文档是很危险的。让我们看看为什么会这样。
为什么在分布式搜索中深度分页是十分危险的?
当搜索匹配 Elasticsearch 中的很多文档时,默认情况下,会返回第一页的内容并包括最前的 10 个结果。搜索 API 有参数 from 和 size 指定搜索结果的深度。例如,如果想看排名第 50 到 60 的文档,那么参数值应该是 from=50 和 size=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 集群 - 之三的更多相关文章
- 解剖 Elasticsearch 集群 - 之二
解剖 Elasticsearch 集群 - 之二 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论 Elasticsearch 是如何处理 3C ...
- 解剖 Elasticsearch 集群 - 之一
解剖 Elasticsearch 集群 - 之一 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论底层的存储模型以及 CRUD(创建.读取.更新 ...
- Ubuntu 14.04中Elasticsearch集群配置
Ubuntu 14.04中Elasticsearch集群配置 前言:本文可用于elasticsearch集群搭建参考.细分为elasticsearch.yml配置和系统配置 达到的目的:各台机器配置成 ...
- elasticsearch 集群
elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他们搭建成为一个集群 基本配置 每个节点都要进行这样的配置: cluster.name: ba ...
- 我的ElasticSearch集群部署总结--大数据搜索引擎你不得不知
摘要:世上有三类书籍:1.介绍知识,2.阐述理论,3.工具书:世间也存在两类知识:1.技术,2.思想.以下是我在部署ElasticSearch集群时的经验总结,它们大体属于第一类知识“techknow ...
- Elasticsearch集群中处理大型日志流的几个常用概念
之前对于CDN的日志处理模型是从logstash agent==>>redis==>>logstash index==>>elasticsearch==>&g ...
- elasticsearch 集群配置
2015-10-10 09:56 by 轩脉刃, 999 阅读, 1 评论, 收藏, 编辑 elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他 ...
- 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(5)
数据操作与REST API(Data manipulation with REST API) ElasticSearch REST API可用于各种任务.多亏了它,我们可以管理索引,更改实例参数,检查 ...
- Elasticsearch集群搭建
现有两部机器:192.168.31.86,192.168.31.87 参考以往博文对Elasticsearch进行配置完成:http://www.cnblogs.com/zhongshengzhe ...
随机推荐
- loadView 再思考
如果使用代码创建view,那么就需要重写loadView方法: 在这个方法中,如果不创建view,就会循环的调用loadView. - (void)loadView { UIView *view = ...
- 关于数据结构的10个面试题(c语言实现)
关于数据结构的10个面试题(c语言实现) 2010-04-21 22:17 5702人阅读 评论(0) 收藏 举报 数据结构面试c语言bttree 1. 输入一个链表的头结点,从尾到头 ...
- springMVC文件上传优化
1. 新建web project 2. 填 jar,注意新加入两个上传文件的jar, commons-io, commons-fileupload 3. 改写web.xml <?xml vers ...
- tset
test fsdfs jsjf sdfsdfsdfsdf sfs fsfsfs test112 sdfs sdfsdf sdfs sf af s sdf sadfasdfsa asfasf sdfsa ...
- swfobject.embedSWF属性与用法
JS+flash的焦点幻灯片既能大方得体的展示焦点信息,也能美轮美奂的展示图片,越来越多的网站使用这种焦点幻灯的表现方法.很多童鞋在下载这方面的素材代码的时候,往往会因为展示出来的是flash,觉得难 ...
- spring boot + neo4j restful
整整折腾了三天,终于把spring boot + neo4j的路走通了. 这里介绍3个部分,pom,entity,repository 1)pom <?xml version="1.0 ...
- ZenCoding 个人理解和总结
我的理解:ZenCoding是一个html简写的语法,可以最快速的生成html. 不少IDE应该都支持,我用的intellij idea是支持的. ZenCoding表示和CSS/JS有相通之处,比如 ...
- 常用HQL集锦
1.根据ID查询某"一个"实体类 方法1: String hql = "From ClassEntity as c where c.id=?"; ClassEn ...
- IP组播技术介绍及实现例子
引 言 近年来,随着Internet的迅速普及和爆炸性发展,在Internet上产生了许多新的应用,其中不少是高带宽的多媒体应用,譬如网 络视频会议.网络音频/视频广播.AOD/VOD.股市行情发布. ...
- ubuntu上安装vsftp-使用java进行匿名链接
检查环境: 1. 检查是否装过了ftp服务器 如果没有提示内容折,本机没有安装. root@hadoops:~# rpm -qa|grep vsftpdroot@hadoops:~# rpm -qa| ...