《深刻理解Elasticsearch(原书第2版)》——第1章  Elasticsearch简介

第1章  Elasticsearch简介 

摘要: 欢迎来到Elasticsearch的世界并阅读本书第2版。经过阅读本书,咱们将带领你接触与Elasticsearch紧密相关的各类话题。请注意,本书不是为初学者写的。笔者将本书做为《Elasticsearch Server, Second Edition》的续做和姊妹篇。html


image

前  言
欢迎来到Elasticsearch的世界并阅读本书第2版。经过阅读本书,咱们将带领你接触与Elasticsearch紧密相关的各类话题。请注意,本书不是为初学者写的。笔者将本书做为《Elasticsearch Server, Second Edition》的续做和姊妹篇。相对于《Elasticsearch Server》,本书涵盖了不少新知识,不过你偶尔也能够在本书中发现一些引自《Elasticsearch Server》的内容。
本书将探讨与Elasticsearch和Lucene相关的多个不一样主题。首先,咱们以介绍Lucene和Elasticsearch的基本概念做为开始,带领读者认识Elasticsearch提供的众多查询方式。在这里,将涉及和查询相关的不一样主题,好比结果过滤以及如何为特定场景选择合适的查询方式。显然,Elasticsearch不只仅只有查询功能。所以,本书还将介绍Elasticsearch新加入的汇集功能,以及众多可以赋予被索引数据意义的特性,并设法提供更佳的用户查询体验。
对大多数用户来讲,查询和数据分析是Elasticsearch最吸引人的部分,不过这些还不是咱们想要探索的所有内容。所以,本书在涉及索引架构时还会试图跟读者探讨一些额外话题,好比如何选择合适的分片数和副本数,如何调整分片分配行为等。当谈论Elasticsearch和Lucene之间的关系时,咱们还将介绍不一样的打分算法、算法之间的差别、如何选择合适的存储机制,以及为何须要作此选择。
最后,咱们还将触及Elasticsearch的管理功能,将探讨发现和恢复模块,以及对人类友好的Cat API。Cat API能够帮助咱们快速获取相关的运维信息,它的返回数据组织成一种大多数人都易于阅读的格式,无需进行JSON解析。咱们还将认识和使用部落节点,它可以为咱们提供在多个节点间联合查询的能力。
由于本书的书名,咱们没法忽略与性能相关的话题,因此咱们决定用整整一章来探讨性能。咱们谈论了文档取值及其相关改进,还介绍了垃圾回收器的工做方式,以及在垃圾回收器未能如咱们指望般工做时能够作些什么。最后,探讨了如何扩展Elasticsearch以应对高索引量和查询量的场景。
和本书第1版同样,咱们决定以开发Elasticsearch插件的话题做为本书结尾。咱们将展现如何构建Apache Maven项目,并开发两个不一样类型的插件—自定义REST操做插件和自定义分析插件。
假如你在读完某些主题后对其产生浓厚的兴趣,那么这本书就是适合你的。但愿你在读完后可以喜欢这本书。
本书主要内容
第1章先介绍Apache Lucene的工做方式,再介绍Elasticsearch的基本概念,并演示Elasticsearch内部是如何工做的。
第2章描述Lucene评分过程,为何要进行查询改写,什么是查询模板以及如何使用查询模板。除此以外,还介绍了过滤器的使用,以及如何为特定场景选择合适的查询方式。
第3章描述了查询二次评分、多匹配控制,并介绍了用于作查询分析的各类聚合类型。关键词项聚合和最优词项聚合能够根据所含内容片断对文档进行归类。除此以外,还介绍了Elasticsearch的parent-child文档关系处理,并提供了在Elasticsearch中使用脚本的相关知识。
第4章覆盖了有关用户体验提高的相关话题。本章介绍了查询建议(suggester),它能帮助修正查询中的拼写错误并构建高效的自动完成(autocomplete)机制。除此以外,经过实际的案例展现如何经过使用不一样查询类型和Elasticsearch的其余功能来提升查询相关性。
第5章介绍了如下技术:如何选择合适的分片及副本数,路由是如何工做的,索引分片机制是如何工做的以及如何影响分片行为。同时介绍了什么是查询执行偏好,以及它是如何影响查询执行的。
第6章描述如何修改Lucene评分以及如何选择备用的评分算法。本章也介绍了Elasticsearch的准实时搜索和索引,事务日志的使用,理解索引的段合并,以及如何调整段合并来适应应用场景。在本章最后,还将介绍Elasticsearch的缓存机制和请求打断器,以免出现内存用尽的故障。
第7章介绍了什么是发现、网关、恢复模块,如何配置这些模块,以及有哪些使人心烦的疑难点。还介绍了什么是Cat API,如何把数据备份到各类云服务上(好比亚马逊的AWS和微软的Azure),以及如何从云服务上恢复数据。最后还介绍了如何使用部落节点进行联盟搜索。
第8章覆盖了与Elasticsearch性能相关的各类主题,从使用文档取值来优化字段数据缓存的内存使用,到JVM垃圾回收器的工做原理,再到查询基准测试,最后到如何扩展Elasticsearch以适应更高的索引量和查询量场景。
第9章经过演示如何开发你本身的REST操做插件和查询语言分析插件来介绍Elasticsearch的插件开发。
阅读本书的必备资源
本书写做时采用了Elasticsearch的1.4.x版本,全部的范例代码应该能在该版本下正常运行。除此以外,读者须要一个能发送HTTP请求的命令行工具,例如curl,该工具在绝大多数操做系统上是可用的。请记住,本书的全部范例都使用了curl。若是读者想使用其余工具,请注意检查请求的格式,以保证你所选择的工具能正确解析它。
除此以外,为了运行第9章的范例,须要读者的机器上已安装了JDK,而且须要一个编辑器来开发相关代码(或者相似Eclipse的Java IDE)。另外,还要求使用Apache Maven进行代码的管理与构建。
本书的目标读者
本书的目标读者是那些对Elasticsearch基本概念已经很熟悉可是又想深刻了解其自己,同时也对Apache Lucene、JVM垃圾收集感兴趣的Elasticsearch用户和发烧友。除此以外,想了解如何改进查询相关性、如何使用Elasticsearch Java API、如何编写自定义插件的读者,也会发现本书的趣味性和实用性。
若是你是Elasticsearch的初学者,连查询和索引这些基本概念都不熟悉,那么你会发现本书的绝大多数章节难以理解,由于这些内容假定读者已经有相关背景知识。若是是这种状况,建议参考Packt出版社出版的另外一本关于Elasticsearch的图书—《Elasticsearch Server, Second Edition》。node

1.1 Apache Lucene简介

为了全面理解Elasticsearch的工做原理,尤为是索引和查询处理环节,对Apache Lucene的理解显得相当重要。揭开Elasticsearch神秘的面纱,你会发现它在内部使用Apache Lucene建立索引,同时也使用Apache Lucene进行搜索。在接下来的几页里,将向读者展现Apache Lucene的基本概念,特别是那些历来没有使用过Lucene的读者们。算法

1.1.1 熟悉Lucene

读者也许会好奇,为何Elasticsearch的创始人决定使用Apache Lucene而不是开发一个本身的全文检索库。对于这个问题,笔者并非很肯定,毕竟咱们不是这个项目的创始人,咱们猜测是由于Lucene的如下特色而获得了创始人的青睐:成熟,高性能,可扩展,轻量级以及强大的功能。Lucene内核能够建立为单个Java库文件,而且不依赖第三方代码,用户可使用它提供的各类所见即所得的全文检索功能进行索引和搜索操做。固然,Lucene还有不少扩展,它们提供了各类各样的功能,例如多语言处理、拼写检查、高亮显示等。若是不须要这些额外的特性,能够下载单个的Lucene core库文件,直接在应用程序中使用它。数据库

1.1.2 Lucene的整体架构

尽管咱们能够直接探讨Apache Lucene架构的细节,可是有些概念仍是须要提早了解的,以便于更好地理解Lucene的架构,它们包括:apache

  • 文档(document):索引与搜索的主要数据载体,它包含一个或多个字段,存放将要写入索引的或将从索引搜索出来的数据。
  • 字段(field):文档的一个片断,它包括字段的名称和字段的内容两个部分。
  • 词项(term):搜索时的一个单位,表明了文本中的一个词。
  • 词条(token):词项在字段文本中的一次出现,包括词项的文本、开始和结束的偏移以及词条类型。

Apache Lucene将写入索引的全部信息组织为倒排索引(inverted index)的结构形式。倒排索引是一种将词项映射到文档的数据结构,它与传统的关系数据库的工做方式不一样。你能够认为倒排索引是面向词项的而不是面向文档的。咱们来看看简单的倒排索引是什么样的。例如,假设咱们有一些只包含title字段的文档,以下所示:json

  • Elasticsearch Server(文档1)
  • Mastering Elasticsearch(文档2)
  • Apache Solr 4 Cookbook(文档3)

这些文档索引好之后,可简略地显示以下图:

数组


正如你所见,每一个词项指向该词项所出现过的文档数。这种索引组织方式容许快速有效的搜索操做,例如基于词项的查询。除了词项自己之外,每一个词项有一个与之关联的计数(即文档频率),该计数能够告诉Lucene这个词项在多少个文档中出现过。
每一个索引由多个段(segment)组成,每一个段写入一次可是查询屡次。索引期间,一个段建立之后再也不修改。例如,文档被删除之后,删除信息单独保存在一个文件中,而段自己并无被修改
多个段将会在段合并(segments merge)阶段被合并在一块儿。或者强制执行段合并,或者由Lucene的内在机制决定在某个时刻执行段合并,合并后段的数量更少,可是更大。段合并不是常耗费I/O,合并期间有些再也不使用的信息将被清理掉,例如,被删除的文档。对于容纳相同数据的索引,段的数量更少的时候搜索速度更快。尽管如此,仍是须要强调一下:由于段合并不是常耗费I/O,请不要强制进行段合并,你只须要仔细配置段合并策略,剩余的事情Lucene会自行完成。
 若是你想知道段由哪些文件组成以及每一个文件都存储了什么信息,请参考Apache Lucene的官方文档:http://lucene.apache.org/core/4_10_3/core/org/apache/lucene/codecs/lucene410/pa-ckage-summary.html。
更深刻地了解Lucene索引
固然,实际的Lucene索引比前面提到的更复杂、更高深,除了词项的文档频率和出现该词项的文档列表外,还包含其余附加信息。在这里咱们会介绍一些索引中的附加信息。了解这些信息对咱们颇有帮助,尽管它们只在Lucene内部使用。
(1)norm
norm是一种与每一个被索引文档相关的因子,它存储文档的归一化结果,被用于计算查询的相关得分。norm基于索引时的文档加权值(boost)计算得出,与文档一块儿被索引存储。使用norm可让Lucene在创建索引时考虑不一样文档的权重,不过须要一些额外的磁盘空间和内存来索引和存储norm信息。
(2)词项向量
词项向量(term vector)是一种针对每一个文档的微型倒排索引。词项向量的每一个维由词项和出现频率结对组成,还能够包括词项的位置信息。Lucene和Elasticsearch默认都禁用词项向量索引,不过要实现某些功能,如关键词高亮等须要启用这个选项。
(3)倒排项格式
随着Lucene 4.0的发布,Lucene引入了解码器架构,容许开发者控制索引文件写入磁盘的格式,倒排项就是索引中可定制的部分之一。倒排项中能够存储字段、词项、文档、词项位置和偏移以及载荷(payload,一个在Lucene索引中随意存放的字节数组,能够包含任何咱们须要的信息)。针对不一样的使用目的,Lucene提供了不一样的倒排项格式。好比,有一种优化后的格式是专门为高散列范围字段如惟一标识提供的。
(4)doc values
咱们前面提到过,Lucene索引是一种倒排索引。不过,针对某些功能,如切面(faceting)或聚合(aggregation),这种倒排索引架构就不是最佳选择。这类功能一般须要操做文档而不是词项,Lucene须要把索引翻转过来构成正排索引才能完成这些功能所须要的计算。基于这些考虑,Lucene引入了doc values和额外的数据结构来进行分组、排序和聚合。doc values存储字段的正排索引。Lucene和Elasticsearch都容许咱们经过配置来指定doc values的存储实现方式。可选的存储实现包括基于内存的、基于硬盘的,以及两者的混合。缓存

1.1.3 分析数据

读者也许会好奇,文档中的数据是如何转化为倒排索引的?查询串又是怎么转换为能够用于搜索的词项的?这个转换过程被称为分析(analysis)。
文本分析由分析器来执行,它创建在分词器(tokenizer)、过滤器(filter)及字符映射器(character mapper)之上。
Lucene的分词器用来将文本切割成词条,词条是携带各类额外信息的词项,这些信息包括:词项在原始文本中的位置,词项的长度。分词器工做的结果被称为词条流,由于这些词条被一个接一个地推送给过滤器处理。
除了分词器,过滤器也是Lucene分析器的组成部分。过滤器数额可选,能够为零个、一个或多个,用于处理词条流中的词条。例如,它能够移除、修改词条流中的词条,甚至能够创造新的词条。Lucene中有不少现成的过滤器,你也能够根据须要实现新的过滤器。如下是一些过滤器的例子。
小写过滤器:将全部词条转化为小写。
ASCII过滤器:移除词条中全部非ASCII字符。
同义词过滤器:根据同义词规则,将一个词条转化为另外一个词条。
多语言词干还原过滤器:将词条的文本部分归约到它们的词根形式,即词干还原。当分析器中有多个过滤器时,会逐个处理,理论上能够有无限多个过滤器。
过滤器能够一个接一个地被调用,所以咱们能够经过逐个添加多个过滤器的方式来得到近乎无限的分析能力。
最后咱们介绍字符映射器,它用于调用分词器以前的文本预处理操做。字符映射器的一个例子就是HTML文本的去标签处理。
索引与查询
也许读者会好奇,Lucene以及全部基于Lucene的软件是如何控制索引及查询操做的?在索引期,Lucene会使用你选择的分析器来处理文档中的内容,能够对不一样的字段使用不一样的分析器,例如,文档的title字段与description字段就可使用不一样的分析器。
在检索时,若是你使用了某个查询分析器(query parser),那么你的查询串将会被分析。固然,你也能够选择不分析数据。有一点须要牢记,Elasticsearch中有些查询会被分析,而有些则不会被分析。例如,前缀查询(prefix query)不会被分析,而匹配查询(match query)会被分析。
你还应该记住,索引期检索期的文本分析要采用一样的分析器,只有查询(query)分词出来的词项与索引中词项能匹配上,才会返回预期的文档集。例如,若是在索引期使用了词干还原与小写转换,那么在查询期,也应该对查询串作相同的处理,不然,查询可能不会返回任何结果。安全

1.1.4 Lucene查询语言

Elasticsearch提供的一些查询类型(query type)支持Apache Lucene的查询解析语法,所以,咱们应该深刻了解Lucene的查询语言。
1. 理解基本概念
在Lucene中,一个查询(query)一般被分割为词项与操做符。Lucene中的词项能够是单个的词,也能够是一个短语(用双引号括起来的一组词)。若是查询被设置为要被分析,那么预先选定的分析器将会对查询中的全部词项进行处理。
一个查询也能够包含布尔操做符。布尔操做符链接多个词项,使之构成从句(clause)。有如下这些布尔操做符。
AND:它的含义是,文档匹配当前从句当且仅当AND操做符左右两边的词项都在文档中出现。例如,咱们想执行“apache AND lucene”这样的查询,只有同时包含“apache”和“lucene”这两个词项的文档才会被返回给用户。
OR:它的含义是,包含当前从句中任意词项的文档都被视为与该从句匹配。例如,咱们执行“apache OR lucene”这样的查询,任意包含词项“apache”或词项“lucene”的文档都会返回给用户。
NOT:它的含义是,与当前从句匹配的文档必须不包含NOT操做符后面的词项。例如,咱们执行“lucene NOT elasticsearch”这样的查询,只有包含词项“lucene”且不包含词项“elasticsearch”的文档才会被返回给用户。
除了前面介绍的那些操做符之外,咱们还可使用如下这些操做符。
+:它的含义是,只有包含了“+”操做符后面词项的文档才会被认为与从句匹配。例如,咱们想查找那些必须包含“lucene”可是“apache”可出现可不出现的文档,可执行以下查询:“+lucene apache”。
–:它的含义是,与从句匹配的文档,不能出现“-”操做符后的词项。例如,咱们想查找那些包含了“lucene”可是不包含“Elasticsearch”的文档,能够执行以下查询:“+lucene -elasticsearch”。
若是查询中没有出现前面提到过的任意操做符,那么默认使用OR操做符。
除了前面介绍的内容以外,有一件事情值得一提:可使用圆括号对从句进行分组,以构造更复杂的从句,例如:
网络

2. 在字段中查询
就像Elasticsearch的处理方式那样,Lucene中全部数据都存储在字段(field)中,而字段又是文档的组成单位。为了实现针对某个字段的查询,用户须要提供字段名称,再加上冒号以及将要在该字段中执行查询的从句。若是你想查询全部在“title”字段中包含词项“Elasticsearch”的文档,可执行如下查询:
image

也能够在一个字段中同时使用多个从句,例如,若是你想查找全部在“title”字段中同时包含词项“Elasticsearch”和短语“mastering book”的文档,可执行以下查询:

固然,上面的查询也能够写成下面这种形式:

3. 词项修饰符
除了使用简单词项和从句的常规字段查询之外,Lucene容许用户使用修饰符(modifier)修改传入查询对象的词项。毫无疑问,最多见的修饰符就是通配符(wildcard)。Lucene支持两种通配符:?和*。前者匹配任意一个字符,然后者匹配多个字符。
 请记住,出于对性能的考虑,通配符不能做为词项的第一个字符出现。
除通配符以外,Lucene还支持模糊(fuzzy and proximity)查询,办法是使用“~”字符以及一个紧随其后的整数值。当使用该修饰符修饰一个词项时,意味着咱们想搜索那些包含该词项近似词项的文档(因此这种查询称为模糊查询)。~字符后的整数值肯定了近似词项与原始词项的最大编辑距离。例如,当咱们执行查询writer~2,意味着包含词项writer和writers的文档均可以被视为与查询匹配。
当修饰符~用于短语时,其后的整数值用于告诉Lucene词项之间多大距离是能够接受的。例如,咱们执行以下查询:

在title字段中包含mastering Elasticsearch的文档被视为与查询匹配,而包含mastering book Elasticsearch的文档则被认为不匹配。而若是咱们执行下面这个查询:

title:"mastering Elasticsearch"~2,

则这两个文档都被认为与查询匹配。
此外,还可使用^字符并赋以一个浮点数对词项加权(boosting),从而提升该词项的重要程度。若是都被加权,则权重值较大的词项更重要。默认状况下词项权重为1。能够参考2.1节进一步了解什么是权重值(boost value),以及其在文档评分中的做用。
咱们也可使用方括号和花括号来构建范围查询。例如,咱们想在一个数值类型的字段上执行一个范围查询,执行以下查询便可:
image

上面查询的返回文档的price字段的值大于等于10.00并小于等于15.00
固然,咱们也能够在字符串类型的字段上执行范围查询(range query),例如:name:[Adam TO Adria]
上面查询的返回文档的name字段中,包含了按字典顺序介于Adam 和Adria之间(包括Adam和Adria)的词项。
若是想执行范围查询同时又想排除边界值,则可以使用花括号做为修饰符。例如,咱们想查找price字段值大于等于10.00但小于15.00的文档,可以使用以下查询:
image

若是想执行一边受限而另外一边不作限制的范围查询,例如,查找price字段值大于等于10.00的文档,可以使用以下查询:
image

4. 特殊字符处理
不少应用场景中,也许你想搜索某个特殊字符(这些特殊字符包括+、–、&&、||、!、(,)、{}、[]、^、"、~、*、?、:、\、/),须要先使用反斜杠对这些特殊字符进行转义。例如,你可能想搜索abc"efg这个词项,须要按以下方式处理:abc\"efg

 

1.2 何为Elasticsearch

当读者手持本书阅读时,可能已经对Elasticsearch有所了解了,至少已经了解了它的一些核心概念和基本用法。不过,为了全面理解该搜索引擎是如何工做的,咱们最好简略地讨论一下它。
也许你已经了解到,Elasticsearch是一个可用于构建搜索应用的成品软件(译者注:区别于Lucene这种中间件)。它最先由Shay Banon建立,并于2010年2月发布。以后的几年,Elasticsearch迅速流行开来,成为其余开源和商业解决方案以外的一个重要选择。它是下载量最多的开源项目之一。

1.2.1 Elasticsearch的基本概念

如今,让咱们浏览一下Elasticsearch的基本概念以及它们的特征。
1. 索引
Elasticsearch将它的数据存储在一个或者多个索引(index)中。用SQL领域的术语来类比,索引就像数据库,能够向索引写入文档或者从索引中读取文档。就像以前说过的那样,Elasticsearch在内部使用Lucene将数据写入索引或从索引中检索数据。读者须要注意的是,Elasticsearch中的索引可能由一个或多个Lucene索引构成,细节由Elasticsearch的索引分片(shard)、复制(replica)机制及其配置决定。
2. 文档
文档(document)是Elasticsearch世界中的主要实体(对Lucene来讲也是如此)。对于全部使用Elasticsearch的案例来讲,它们最终都会被归结到对文档的搜索之上。文档由字段构成,每一个字段包含字段名以及一个或多个字段值(在这种状况下,该字段被称为是多值的,即文档中有多个同名字段)。文档之间可能有各自不一样的字段集合,文档并无固定的模式或强制的结构。这种现象看起来很眼熟(这些规则也适用于Lucene文档)。事实上,Elasticsearch的文档最后都被存储为Lucene文档了。从客户端的角度来看,文档是一个JSON对象(想了解更多关于JSON格式的细节,请参考http://en.wikipedia.org/wiki/JSON)。
3. 类型
**Elasticsearch中每一个文档都有与之对应的类型(type)定义。这容许用户在一个索引中存储多种文档类型,并为不一样文档类型提供不一样的映射。若是同SQL领域类比,Elasticsearch的类型就像一个数据库表。
**4. 映射

正如你在1.1节所了解到的那样,全部文档在写入索引前都将被分析。用户能够设置一些参数,决定如何将输入文本分割为词条,哪些词条应该被过滤掉,或哪些附加处理有必要被调用(例如移除HTML标签)。这就是映射(mapping)扮演的角色:存储分析链所需的全部信息。虽然Elasticsearch能根据字段值自动检测字段的类型,有时候(事实上几乎是全部时候)用户仍是想本身来配置映射,以免出现一些使人不愉快的意外。
5. 节点
单个的Elasticsearch的服务实例被称为节点(node)。不少时候部署一个Elasticsearch节点就足以应付大多数简单的应用,可是考虑到容错性或者数据膨胀到单机没法应付这些情况,也许你会更倾向于使用多节点的Elasticsearch集群。
Elasticsearch节点能够按用途分为3类。众所周知,Elasticsearch是用来索引和查询数据的,所以第1类节点就是数据(data)节点,用来持有数据,提供对这些数据的搜索功能。第2类节点指主(master)节点,做为监督者负责控制其余节点的工做。一个集群中只有一个主节点。第3类节点是部落(tribe)节点。部落节点是Elasticsearch 1.0版新引入的节点类型,它能够像桥梁同样链接起多个集群,并容许咱们在多个集群上执行几乎全部能够在单集群Elasticsearch上执行的功能。
6. 集群
多个协同工做的Elasticsearch节点的集合被称为集群(cluster)。Elasticsearch的分布式属性使咱们能够轻松处理超过单机负载能力的数据量。同时,集群也是无间断提供服务的一种解决方案,即使当某些节点由于宕机或者执行管理任务(例如升级)不可用时,Elasticsearch几乎是无缝集成了集群功能。在咱们看来,这是它赛过竞争对手的最主要优势之一。在Elasticsearch中配置一个集群是再容易不过的事了。
7. 分片
正如咱们以前提到的那样,集群容许系统存储的数据总量超过单机容量。为了知足这个需求,Elasticsearch将数据散布到多个物理的Lucene索引上去。这些Lucene索引被称为分片(shard),而散布这些分片的过程叫作分片处理(sharding)。Elasticsearch会自动完成分片处理,而且让用户看来这些分片更像是一个大索引。请记住,除了Elasticsearch自己自动进行分片处理外,用户为具体的应用进行参数调优也是相当重要的,由于分片的数量在索引建立时就被配置好了,以后没法改变,除非建立一个新索引并从新索引所有数据。
8. 副本
分片处理容许用户推送超过单机容量的数据至Elasticsearch集群。副本(replica)则解决了访问压力过大时单机没法处理全部请求的问题。思路是很简单的,为每一个分片建立冗余的副本,处理查询时能够把这些副本看成最初的主分片(primary shard)使用。值得注意的是,副本给Elasticsearch带来了更多的安全性。若是主分片所在的节点宕机了,Elasticsearch会自动从该分片的副本中选出一个做为新的主分片,所以不会对索引和搜索服务产生干扰。能够在任意时间点添加或移除副本,因此一旦你有须要,可随时调整副本的数量。

1.2.2 Elasticsearch架构背后的关键概念

Elasticsearch的架构遵循了一些设计理念。开发团队但愿这个搜索引擎产品易于使用和扩展,这些特征在Elasticsearch的每一个角落里均可以被看到。从架构的视角来看,有下面这些主要特征:

  • 合理的默认配置,使得用户在简单安装之后能直接使用Elasticsearch而不须要任何额外的调优,这其中包括内置的发现(例如,字段类型检测)和自动配置功能。
  • 默认的分布式工做模式。每一个节点老是假定本身是某个集群的一部分或将是某个集群的一部分。 对等架构(P2P)能够避免单点故障。节点会自动链接到集群中的其余节点,进行相互的数据交换和监控操做。这其中就包括了索引分片的自动复制。
  • 容易扩充新节点至集群,不管是从数据容量的角度仍是数量的角度。 Elasticsearch没有对索引中的数据结构强加任何限制。这容许用户调整现有的数据模型。正如以前咱们所描述的那样,Elasticsearch支持在一个索引中存在多种数据类型,容许用户调整业务模型,包括处理文档之间的关联(尽管这种功能很是有限)。
  • 准实时(near real time searching)搜索和版本同步(versioning)。考虑到Elasticsearch的分布式特性,查询延迟和节点之间临时的数据不一样步是难以免的。Elasticsearch尝试减小这些问题,而且提供了额外的机制用于版本同步。

1.2.3 Elasticsearch的工做流程

本节咱们将探索一些关键的Elasticsearch特性,如启动、故障检测、数据索引和查询等。
1. 启动过程
当Elasticsearch节点启动时,它使用发现(discovery)模块来发现同一个集群中的其余节点(这里的关键是配置文件中的集群名称)并与它们链接。默认状况下,Elasticsearch节点会向网络中发送广播请求,以找到拥有相同集群名称的其余节点。读者能够经过下图的描述来了解相关的处理。

image


集群中有一个节点被选为主(master)节点。该节点负责集群的状态管理以及在集群拓扑变化时作出反应,分发索引分片至集群的相应节点上去。
 请记住,从用户的角度来看,Elasticsearch中的管理节点并不比其余节点重要,这与其余的某些分布式系统不一样(例如数据库)。在实践中,你不须要知道哪一个节点是管理节点,全部操做能够发送至任意节点,Elasticsearch内部会自行处理这些难以想象的事情。若是有须要,任意节点能够并行发送子查询给其余节点,并合并搜索结果,而后返回给用户。全部这些操做并不须要通过管理节点处理(请记住,Elasticsearch是基于对等架构的)。
管理节点读取集群的状态信息,若是有必要,它会进行恢复(recovery)处理。在该阶段,管理节点会检查有哪些索引分片,并决定哪些分片将用做主分片。此后,整个集群进入黄色状态。
意味着集群能够执行查询,可是系统的吞吐量以及各类可能的情况是未知的(这种情况能够简单理解为全部的主分片已经被分配了,可是副本没有被分配)。下面的事情就是寻找到冗余的分片用做副本。若是某个主分片的副本数过少,管理节点将决定基于某个主分片建立分片和副本。若是一切顺利,集群将进入绿色状态(这意味着全部主分片以及副本均已分配好)。
2. 故障检测
集群正常工做时,管理节点会监控全部可用节点,检查它们是否正在工做。若是任何节点在预约义的超时时间内不响应,则认为该节点已经断开,而后错误处理过程开始启动。这意味着可能要在集群–分片之间从新作平衡,选择新的主节点等。对每一个丢失的主分片,一个新的主分片将会从原来的主分片的副本中选出来。新分片和副本的放置策略是可配置的,用户能够根据具体需求进行配置。更多的信息能够在第7章了解到。
为了描述故障检测(failure detection)是如何工做的,咱们用一个只有3个节点的集群做为例子,将会有一个管理节点,两个数据节点。管理节点会发送ping请求至其余节点,而后等待响应。若是没有响应(实际上多少次ping请求无响应能够确认节点失败取决于配置),则该节点会被从集群中移除出去。相反地,全部节点也会向主节点发送ping请求来检查主节点是否在正常工做。节点之间的相互探测以下图所示。


3. 与Elasticsearch通讯
前面已经讨论过Elasticsearch是如何构建的了,然而,对普通用户来讲,最重要的部分是如何向Elasticsearch推送数据以及构建查询。为了提供这些功能,Elasticsearch对外公开了一个设计精巧的API。若是咱们说,基本上每一个Elasticsearch功能模块都有一个API,这将是使人鼓舞的。这个主API是基于REST的(REST细节请参考http://en.wikipedia.org/wiki/Representational_state_transfer),而且在实践中能轻松整合到任意支持HTTP协议的系统中去。
Elasticsearch假设数据由URL携带或者以JSON(JSON细节请参考(http://en.wikipedia.org/wiki/JSON)文档的形式由HTTP消息体携带。使用Java或者基于JVM语言的用户,应该了解一下Java API,它除了REST API提供的全部功能之外还有内置的集群发现功能。
值得一提的是,Elasticsearch在内部也使用Java API进行节点间通讯。所以,Java API提供了全部可被REST API调用的功能。
(1)索引数据
Elasticsearch提供了多种索引数据的方式。最简单的方式是使用索引API,它容许用户发送一个文档至特定的索引。例如,使用curl工具(curl细节请参考http://curl.haxx.se/),可使用以下命令建立一个文档:

第2种方式容许用户经过bulk API或UDP bulk API一次发送多个文档至集群。二者的区别在于网络链接方式,前者使用HTTP协议,后者使用UDP协议。后者速度快,可是不可靠。还有一种方式使用被叫做河流(river)的插件来发送数据。不过在这里咱们不须要了解这种河流插件,由于它们将在Elasticsearch将来版本中被移除。
有一件事情须要记住,建索引操做只会发生在主分片上,而不是副本上。当一个索引请求被发送至一个节点上时,若是该节点没有对应的主分片或者只有副本,那么这个请求会被转发到拥有正确的主分片的节点。而后,该节点将会把索引请求群发给全部副本,等待它们的响应(这一点能够由用户控制),最后,当特定条件具有时(好比说达到规定数目的副本都完成了更新时)结束索引过程。
下图展现了咱们刚刚探讨的索引处理过程。

image


(2)查询数据
查询API占据了Elasticsearch API的大部分。使用查询DSL(基于JSON的可用于构建复杂查询的语言),咱们能够作下面这些事情:

  • 使用各类查询类型,包括,简单的词项查询,短语查询,范围查询,布尔查询,模糊查询,区间查询,通配符查询,空间查询,以及具有人类可读的打分控制功能的函数查询,等等。
  • 组合简单查询构建复杂查询。
  • 文档过滤,在不影响评分的前提下抛弃那些不知足特定查询条件的文档。- 这一点能够提高性能。
  • 查找与特定文档类似的文档。
  • 查找特定短语的查询建议和拼写检查。
  • 使用切面构建动态导航和计算各类统计量。

使用预搜索(prospective search)和查找与指定文档匹配的query集合。
谈到查询操做,读者应该了解一个很重要的事实:查询并非一个简单的、单步骤的操做。通常来讲,查询分为两个阶段:分散阶段(scatter phase)和合并阶段(gather phase)。在分散阶段将查询分发到包含相关文档的多个分片中去执行查询,而在合并阶段则从众多分片中收集返回结果,而后对它们进行合并、排序,进行后续处理,而后返回给客户端。该机制能够由下图描述。


 Elasticsearch对外提供了6个系统参数,经过使用其中之一来定制分散/合并机制。在本书的姐妹版《Elasticsearch Server, Second Edition》(Packt出版社)中已经讨论过这个问题了。

1.3 在线书店示例

本书可做为《Elasticsearch server, Second Edition》一书的延续。所以,咱们在这里也沿用在那本书中的案例。总的来讲,假设本身正在实现和运做一个在线书店。
首先须要一个library索引,它的映射定义以下:

这段映射代码位于随书提供的library.json文件。
咱们将要使用的数据也能够在随书提供的books.json文件中找到。这个文件中的文档示例以下:

读者能够从本身在http://www.packtpub.com 的我的帐户中下载全部已购Packt书籍的示例代码文件。若是您从其余地方购买本书,能够访问http://www.packtpub.com/support 进行登记,随后Packt出版社会把文件经过e-mail发送给您。

咱们须要执行以下命令来建立带以上映射的索引,并索引数据:

1.4 小结

在本章中,咱们了解了Apache Lucene的通常架构,例如它的工做原理,文本分析过程是如何完成的,如何使用Apache Lucene查询语言。此外,咱们还讨论了Elasticsearch的一些基本概念,例如它的基本架构和内部通讯机制。 下一章将学习Apache Lucene的默认评分公式,什么是查询重写过程(query rewrite process)以及它是如何工做的。除此以外,还将讨论Elasticsearch的一些功能,例如查询模板、过滤器,以及它们影响查询性能的机制。咱们将学习如何使用过滤器,并选择合适的查询方式来完成查询工做。

相关文章
相关标签/搜索