Elasticsearch 架构原理
为什么要学习架构?
Elasticsearch的一些架构设计,对我们做性能调优、故障处理,具有非常重要的影响。下面将从Elasticsearch的准实时索引的实现、自动发现、rounting和replica的读写过程,shard的allocate控制
使文本可以被搜索?
在传统的数据库中,一个字段存一个值,但是这对于全文搜索是不足的。想要让文本中的而每个单词都可以被搜索,这意味着数据库需要多个值。
支持一个字段多个值的最佳数据结构是倒排索引。倒排索引包含了出现在所有文档中唯一的值或或词的有序列表,以及每个词所属的文档列表。

倒排索引存储了比包含一个term的文档列表多地多的信息,它可能包含每一个term的文档数量,一个term出现在制定文档中的频次,每个文档中term的顺序,每个文档的长度,所有文档的平均长度等等。这些统计信息让Elasticsearch知道哪些term更重要,哪些文档更重要,也就是相关性。
在全文搜索的早些时候,会为整个文档集合建立一个大索引,并且写入磁盘。只有新索引准备好了它就会替代旧肚饿索引,最近的修改可以被检索。
不可变性
写入磁盘的倒排索引是不可变的,它有如下好处:
- 不需要锁。如果从来不需要跟新一个索引,就不必担心多个程序见同时尝试修改。
- 一旦索引被读入文件系统的缓存,它就一直在那儿,因为不会改变。只要文件系统缓存有足够的空间,大部分的读会直接访问内存而不是磁盘。这有助于性能的提升。
- 在索引的声明周期内,所有的其他缓存都可用。他们不需要再每次数据变化了都重建,因此数据不会变。
- 写入单个大的倒排索引,可以压缩数据,较少的磁盘IO和需要缓存索引的大小。
当然,不可变的索引有它的缺点,首先是它不可变。如果想要搜索一个新文档,必须重建整个索引。这不仅限制了一个索引所能装下的数据,还有一个索引可以被更新的频次。
准实时索引的实现?
本文主要介绍Elasticsearch的准实时索引的实现,至于基于Lucene的倒排索引将不在这里介绍,有兴趣的读者可以去Lucene的相关文章,或者阅读《Lucene in Action》等书籍。下面将介绍Elasticsearch索引流程中发生的具体操作,重点在于其中的segment、buffer和translog三部分对性能方面的影响。
1、动态更新的Lucnee索引
要做到实时跟新条件下数据的可用和可靠,就需要在倒排索引的基础上,再做一系列更高级的处理。总结一下Lucene的处理办法:新收到的数据写入新的索引文件里。Lucene把每次生成的倒排索引,叫做一个段(segment)。然后另外使用一个commit文件,记录索引内的所有segment。而生成segment的数据来源,则是内存中的buffer,也就是说,动态跟新过后过程如下:1)当前磁盘上有三个segement可用,同时有一个commit文件记录当前的segment2)新收到的数据进入内存buffer,索引状态如下所示。3)buffer刷到磁盘,生成一个新的segment,commit文件同步跟新。这样可以完成跟新,也产生了几个问题:1、每次一有数据就刷新到磁盘,会增大对磁盘的操作2、刷新到磁盘的时间占据很大一部分时间3、如果刷新的过程中刷新失败应该怎么控制呢?


2、删除和更新
segment是不可变的,所以文档即不能从旧的段中删除,旧的段也不能更新以反映文档最新的文本。相反,每一个提交点包括一个.del文件,包含了段上已经被删除的文档当一个文档被删除,它是实际上只是在.del文件中被标记删除,亦然可以匹配查询,但最终返回之前会被从结果中删除。文档的跟新操作是类似的:当一个文档被更新,旧版本的文档被标记为删除,新版本的文档在新的段中索引。也许该文档的不同版本都会匹配一个查询,但是老版本会从结果中删除。
3、利用磁盘缓存实现的准实时检索
既然涉及到磁盘,那么一个不可避免的问题就来了:磁盘太慢了!对我们要求的实时性很高的服务来说,这种处理还不够。所以,在刚刚第3步的处理中,还有一个中间状态:1)内存buffer生成一个新的segment,刷到文件系统缓存中,Lucene即可检索到这个新的segment,索引状态如图所示。2)文件系统缓存真正同步到磁盘上,commit文件跟新。刷到文件系统缓存中这个步骤,Elasticsearch默认1s的时间间隔,这也就是说相当于是实时搜索的,Elasticsearch也提供了单独的/_reflush接口,用户如果对1s间隔还是不太满意,可以主动调用接口来保证搜索可见。
POST /_refresh <1>POST /blogs/_refresh <2>
- <1> refresh所有索引
- <2> 只refresh 索引
blogs
一般来说我们会通过/_settings接口或者定制template的方式,加大refresh_interval参数:
PUT /my_logs/_settings{ "refresh_interval": -1 } <1>PUT /my_logs/_settings{ "refresh_interval": "1s" } <2>
- <1> 禁用所有自动refresh
- <2> 每秒自动refresh
4、translog提供的磁盘同步控制
既然refresh只是写到文件系统缓存中,那么最后一步写到实际磁盘又是由什么来控制的呢?如果这期间发生主机错误、硬盘故障等异常情况,数据会不会丢失?这里,其实Elasticsearch提供了另一个机制来控制。Elasticsearch也把数据写入到内存buffer的同时,其实还另外记录了一个treanslog的日志。也就是说,在内存数据进入到buffer这一步骤时,其实还另外记录了一个translog记录。
Elasticsearch 架构原理的更多相关文章
- Elasticsearch架构原理
架构原理 本书作为 Elastic Stack 指南,关注于 Elasticsearch 在日志和数据分析场景的应用,并不打算对底层的 Lucene 原理或者 Java 编程做详细的介绍,但是 Ela ...
- 【分布式搜索引擎】Elasticsearch分布式架构原理
一.相关概念介绍 1)集群(cluster) 一个集群(cluster)由一个或多个节点组成. 这些节点具有相同的cluster.name,它们协同工作,分享数据和负载.当加入新的节点或者删除一个节点 ...
- zz《分布式服务架构 原理、设计与实战》综合
这书以分布式微服务系统为主线,讲解了微服务架构设计.分布式一致性.性能优化等内容,并介绍了与微服务系统紧密联系的日志系统.全局调用链.容器化等. 还是一样,每一章摘抄一些自己觉得有用的内容,归纳整理, ...
- ElasticSearch工作原理与优化
elasticsearch设计的理念就是分布式搜索引擎,底层其实还是基于lucene的,通过倒排索引的方式快速查询.比如一本书的目录是索引,然后快速找到每一章的的文本内容这种叫正向索引:而如果一件衣服 ...
- NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)
NET/ASP.NET Routing路由(深入解析路由系统架构原理) 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模 ...
- Hbase的架构原理、核心概念
Hbase的架构原理.核心概念 1.Hbase的表.行.列.列族 2.核心组件: Table和region Table在行的方向上分割为多个HRegion, 一个region由[startkey,en ...
- [Spark内核] 第38课:BlockManager架构原理、运行流程图和源码解密
本课主题 BlockManager 运行實例 BlockManager 原理流程图 BlockManager 源码解析 引言 BlockManager 是管理整个Spark运行时的数据读写的,当然也包 ...
- Istio入门实战与架构原理——使用Docker Compose搭建Service Mesh
本文将介绍如何使用Docker Compose搭建Istio.Istio号称支持多种平台(不仅仅Kubernetes).然而,官网上非基于Kubernetes的教程仿佛不是亲儿子,写得非常随便,不仅缺 ...
- Hive的配置| 架构原理
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能. 本质是:将HQL转化成MapReduce程序 1)Hive处理的数据存储在HDFS 2)Hi ...
随机推荐
- python+Selenium之操作滚动条
当我们做测试的时候,如果页面过长,就会定位元素失败,这时可以使用move_to_element方法跳到该元素的位置再操作: from selenium.webdriver.common.action_ ...
- ubuntu 16 .04常见指令整理
删除类指令 sudo rm -rf 文件名 //该指令为直接删除指令 -------------------------------------------------------------- ...
- [转]C#算法题
1:不允许使用循环语句.条件语句,在控制台中打印出1-200这200个数. 参考答案:这里我使用的是递归. static void Main(string[] args) { Print(); Con ...
- 等待页面元素(webdriverwait)
前言 在脚本中加入太多的 sleep 后会影响脚本的执行速度,虽然 implicitly_wait ()这种方法隐式等待方法一定程度上节省了很多时间.但是一旦页面上某些 js 无法加载出来(其实界面元 ...
- iphone数据存储之-- Core Data的使用
一.概念 1.Core Data 是数据持久化存储的最佳方式 2.数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型 在Mac OS X 10.5Leopard及以 ...
- 大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作
第十九章 Scala语言的数据结构和算法19.1 数据结构(算法)的介绍19.2 看几个实际编程中遇到的问题19.2.1 一个五子棋程序19.2.2 约瑟夫问题(丢手帕问题)19.2.3 其它常见算法 ...
- 垂直居中问题不只有 line-height 可以解决,还有一个哥们叫 margin-top
我们都知道,对于一行文本的垂直居中可以通过设置 height 与 line-height 值相等来实现. 那么对于两个嵌套的div ,或者一个div中的多行文本,怎么让被包含的部分实现垂直居中呢?显然 ...
- IE678下,select 诡异的样式
我没有IE6,我用IE5测试的. IE5下的测试结果:貌似只能设置 width ,设置其他的都失效,连 height 都不例外. IE7下的测试结果:垂直居中失效.边框失效,宽高生效. IE8下的测试 ...
- 使用 Qt 获取 UDP 数据并显示成图片
一个项目,要接收 UDP 数据包,解析并获取其中的数据,主要根据解析出来的行号和序号将数据拼接起来,然后将拼接起来的数据(最重要的数据是 R.G.B 三个通道的像素值)显示在窗口中.考虑到每秒钟要接收 ...
- Iterator和ListIterator的区别 ---面试题
Iterator和ListIterator的区别是什么? 下面列出了他们的区别: Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List. Iterator对 ...