解剖 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 ...
随机推荐
- Python3基础 list(enumerate()) 将一个列表的每一个元素转换成 带索引值的元组
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- PAT1012
To evaluate the performance of our first year CS majored students, 为了计算第一年计算机科学学生的表现 we consider the ...
- JQuery UI的拖拽功能
JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...
- Linux命令 理解
RPM常用命令参数列表 1.安装一个包 # rpm -ivh 2.升级一个包 # rpm -Uvh [注意U一定要大写] -i 安装 -U 升线安装 -h 以#显示安装进度 -v 显示附加 ...
- Education Round16
A题:题意:给定国际象棋king的坐标,求能向几个方向移动分析:处理一下边界情况,其他的都是8 #include <iostream> #include <cstdio> #i ...
- Redis状态和信息查看
转自:http://my.oschina.net/tongyufu/blog/405612 redis-cli连接服务器后,使用info命令查看Redis信息和状态: INFO [section] 以 ...
- Jquery使用常见(全)
一.选择器实例 语法 描述 $(this) 当前 HTML 元素 $("p") 所有 <p> 元素 $("p.intro") 所有 class=&q ...
- PHP的Cookie、Session和跟Laravel相关的几点了解
这两天通过对Cookie和Session的查找和了解,网上关于它们两个的基础知识点都是差不多的,也收藏了几篇不错的博客,同时自己做了些实验后,有了以下几点了解: 1.setcookie 这里有三个地方 ...
- 重启机器解决SSL都要输入密码问题
在Nginx或Apache设置了SSL加密后,发现每次重启服务器后都要输入证书设置的密码,比较麻烦,不然Nginx或Apache无法使用,这时可以用私钥来做这件事.生成一个解密的key文件,替代原来k ...
- MySQL show slave status命令参数
? Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLIST用于从属I/O线程.如果线程正在试图连接到主服务器,正在等待来自主服务器的 ...