深入理解ElasticSearch(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-29 17:30:31

点击下载

作者:(美)酷奇(Kuc,R.),(美)罗戈任斯基(Rogozinski,M.)

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

深入理解ElasticSearch

深入理解ElasticSearch试读:

前言

欢迎来到ElasticSearch的世界。通过阅读本书,我们将带你接触与ElasticSearch紧密相关的各种话题。本书会从介绍Apache Lucene及ElasticSearch的基本概念开始。即使读者熟悉这些知识,简略的介绍也是很有必要的,掌握背景知识对于全面理解集群构建、索引文档、搜索这些操作背后到底发生了什么至关重要。

之后,读者将学习Lucene的评分过程是如何工作的,如何影响评分,以及如何让ElasticSearch选择不同的评分算法。本书也将介绍什么是查询重写以及进行查询重写的原因。除此之外,本书还将介绍如何修改查询来影响ElasticSearch的缓存功能以及如何最大限度地使用缓存。

接着你将学习索引控制的相关知识:如何通过设置不同的倒排表格式(posting format)来改变索引字段的写入模式;索引的段合并机制和段合并的重要性,以及如何调整段合并来适应应用场景;深入探讨索引分片(shard)的分配机制、路由机制,以及当数据量、查询量日渐增长时的应对策略。

当然本书也不会遗漏垃圾收集的相关内容,包括垃圾收集的工作原理、触发时间以及如何调整垃圾收集的行为。此外,本书也将涉及ElasticSearch状态诊断的介绍,例如,描述系统段合并状况,ElasticSearch在高级API背后是如何工作以及如何限制I/O操作的。然而,本书并不仅限于讨论ElasticSearch的底层机制,同时也涵盖了如何改进用户搜索体验,例如处理拼写检查,高效地输入自动提示以及如何改进查询等内容。

除了前面介绍的那些,本书还将指导读者熟悉ElasticSearch的Java API,并演示它的使用方法,其中不仅包含CRUD(增删查改)等基本功能,同时也包含集群、索引的维护与操作等高级功能。最后,读者将通过开发一个用于数据索引的自定义river插件,以及一个在检索期和索引期用于数据分析的自定义分析插件来深入了解ElasticSearch的扩展机制。本书主要内容

第1章介绍Apache Lucene的工作方式,以及ElasticSearch的基本概念,并演示Elastic-Search的内部工作机制。

第2章描述Lucene评分过程是如何工作的,为什么要进行查询重写,以及查询二次评分(rescore)是如何工作的。除此之外,还将介绍ElasticSearch的批处理API,以及如何使用过滤器(filter)来优化查询。

第3章描述如何修改Lucene评分,并使用不同的倒排索引格式来改变索引字段的结构。此外还会介绍ElasticSearch的准实时搜索和索引,事务日志的使用,理解索引的段合并以及如何调整段合并来适应应用场景。

第4章介绍以下技术:如何选择恰当的索引分片及复制(replicas)数量,路由是如何工作的,索引分片机制是如何工作的以及如何影响分片行为。同时还介绍ElasticSearch如何进行系统初始配置,以及当数据量和查询量急剧增长时如何调整系统配置。

第5章介绍如何为具体应用选择正确的目录(directory)实现,什么是发现(Discovery)、网关(Gateway)、恢复(Recovery)模块,如何配置这些模块,以及有哪些令人困扰的疑难点。最后介绍如何通过ElasticSearch来查看索引段信息,以及如何进行ElasticSearch缓存机制的调优。

第6章介绍JVM垃圾收集的工作原理和重要意义,以及如何对它进行调优。同时还介绍如何控制ElasticSearch的I/O操作数量,什么是预热器(warmer)以及如何使用它,最后介绍如何诊断ElasticSearch中的问题。

第7章介绍查询建议(suggester),它能帮助修正查询中的拼写错误以及构建高效的自动完成(autocomplete)机制。除此之外,将通过实际的案例展示如何使用不同查询类型和ElasticSearch的其他功能来提高查询相关性。

第8章覆盖ElasticSearch的Java API,不仅包括一些基本API,诸如连接到ElasticSearch集群、单条索引或批量索引、检索文档等,而且涵盖ElasticSearch暴露的一些用于控制集群的API。

第9章通过演示如何开发你自己的河流(river)和语言处理(language)插件来介绍ElasticSearch的插件开发。阅读本书的必备资源

本书基于ElasticSearch 0.90.x版本,所有范例代码均能在该版本下正常运行。除此之外,读者需要一个能发送HTTP请求的命令行工具,如curl,该工具在绝大多数操作系统上是可用的。请记住,本书的所有范例都使用了curl,如果读者想使用其他工具,请注意检查请求的格式从而保证所选择的工具能正确解析它。

除此之外,为了运行第8章和第9章的范例,要求已安装JDK,并且需要一个编辑器来开发相关代码(或者类似Eclipse的Java IDE)。书中这两章都使用Apache Maven进行代码的管理与构建。本书的目标读者

本书的目标读者是那些虽然熟悉ElasticSearch基本概念但又想深入了解其本身,同时也对Apache Lucene、JVM垃圾收集感兴趣的ElasticSearch用户和发烧友。除此之外,想了解如何改进查询相关性,如何使用ElasticSearch Java API,如何编写自定义插件的读者,也会发现本书的趣味性和实用性。

如果你是ElasticSearch的初学者,对查询和索引这些基本概念都不熟悉,那么你会发现本书的绝大多数章节难以理解,因为这些内容假定读者已经具备了相关背景知识。这种情况下,建议参考Packt出版社上一本关于ElasticSearch的图书《ElasticSearch Server》。客户支持

亲爱的读者,请随时浏览http://www.elasticsearchserverbook.com,这里列出了本书最新的勘误表,以及相关的扩展阅读。范例代码下载

如果读者通过http://www.packtpub.com/support并注册账号,我们将通过E-mail将代码发送给你。致谢Rafa Ku的致谢

本书正是我在完成《ElasticSearch Server》一书以后的下一个写作目标。幸运的是,我顺利实现了这个目标。我并不想逐一介绍所有主题,而是精选了一部分来阐述和分享我所了解的知识。与《ElasticSearch Server》类似,我也不会在本书中囊括所有的主题,毕竟很多小细节并不是那么重要(这依赖具体的使用案例),因此会忽略这部分内容。尽管如此,我还是希望读者能轻松获取所有ElasticSearch、Apache Lucene的相关知识细节,并能轻松快速地掌握感兴趣的知识。

在此,我想感谢我的家庭,我在电脑屏幕前全身心投入本书写作的那些日日夜夜里,他们表现出极大的耐心,他们是我最坚强的后盾。

同样也要感谢Sematext所有的同事,尤其是Otis,感谢他为我付出时间,并让我深刻认识到Sematext是一个非常适合我的公司。

最后,非常诚挚地感谢所有ElasticSearch、Lucene项目的创建者和开发者,感谢他们杰出的工作和对开源项目的热情。没有他们,就没有本书的诞生,没有他们,开源搜索引擎就不会有现在这种活力。再次感谢!Marek Rogoziński的致谢

像往常一样,撰写本书是件非常艰巨的任务。这本书不仅涉及更多的高级话题,同时ElasticSearch的代码也在随时改进。ElasticSearch的开发速度并不会变缓,可以毫不夸张地说,每天都会有新东西呈现。请记住,本书是前一本著作的补充和延续,因此,这意味着我们会忽略上一本著作中已经涉及的内容,并补充该书遗漏的内容。现在看看你是否会成功吧!感谢大家。

感谢ElasticSearch、Lucene及所有相关产品的创建者。

同时也要感谢本书的写作和出版团队。尤其要感谢帮助检查错误、校稿、消除表达歧义的伙伴们。

最后,感谢在本书写作期间给予我坚定支持的所有的朋友。作者简介

Rafa Ku是一个很有天资的团队领袖及软件开发人员,现任Sematext集团公司的咨询专家及软件工程师,专注于开源技术,如Apache Lucene、Solr、ElasticSearch和Hadoop stack等,拥有超过11年的软件研发经验,涉及领域广阔,从银行软件到电子商务产品。他主要侧重于Java平台,但对能提高研发效率的任何其他工具或编程语言都抱有极高的热情。同时他也是solr.pl网站的创始人之一,该网站致力于帮助人们解决Solr和Lucene的相关问题。他还是世界范围内各种会议热邀的演讲嘉宾,曾受邀出席过Lucene Eurocon、Berlin Buzzwords、ApacheCon、Lucene Revolution等会议。

Rafa最早于2002年接触Lucene,一开始他并不喜欢这个开源产品,然而在2003年再次使用Lucene时,他改变了自己的看法,并看到了搜索技术的巨大潜力,随后Solr诞生了。Rafa于2010年开始使用ElasticSearch,目前主要关注Lucene、Solr、ElasticSearch和信息检索等方面。

Rafa是《Solr 3.1 Cookbook》一书及其后续版本《Solr 4.0 Cookbook》的作者,同时也是Packt Publishing出版的所有版本的《ElasticSearch Server》的合著者之一。

Marek Rogoziński是一个有着10多年经验的软件架构师和咨询师,专注基于开源搜索引擎(如Solr、ElasticSearch等)的解决方案和大数据分析技术(Hadoop、HBase、Twitter Storm等)。

他是solr.pl网站的联合创始人之一,该网站致力于提供Solr和Lucene的相关资讯,同时他也是Packt Publishing出版的《ElasticSearch Server》的作者之一。

Marek Rogoziński还是一家提供流式大数据处理和分析产品的公司的CTO。评审者简介

Ravindra Bharathi有着10多年的软件工业从业经验,涉及多个领域,如教育、数字媒体营销/广告、企业级搜索、能源管理系统等。兴趣涉及基于搜索的应用软件,包括数据的可视化、插件定制、数据报表等。个人博客地址:http://ravindrabharathi.blogspot.com。

感谢我的妻子Vidya,感谢她对我事业的所有默默付出。

Surendra Mohan目前在一个印度知名软件咨询公司担任Drupal咨询师和架构师。他在加入该公司之前,曾在印度的一些跨国公司服务,并担任过各种角色,如程序员、技术Leader、项目Leader、项目经理、解决方案架构师、服务发布负责人等。他拥有9年左右的Web技术研发经验,涉及媒体、娱乐、房地产、旅游、出版、在线学习、企业级架构等多个领域。他是知名的演讲者,技术涉及Drupal、开源产品、PHP、Moodle等。同时他也是印度孟买各种Drupal科技会议、活动的组织者和发布者。

Surendra Mohan也是一些书籍的评审者,这些书包括《Drupal 7 Multi Site Configuration》《Drupal Search Engine Optimization》《Building e-commerce Sites with Drupal Commerce Cookbook》。除了做技术评审之外,他还撰写了一本关于Apache Solr的著作。

感谢我的家人和朋友们,正是他们对我的不懈支持和鼓励,我才能保质保量完成我的图书评审工作。

Marcelo Ochoa现任教于阿根廷布宜诺斯艾利斯省中部国立大学精确科学与自然科学学院的系统实验室,也是Scotas.com公司的CTO,该公司致力于提供基于Solr和Oracle的准实时搜索解决方案。他在高校任职的同时,也参与了一些与Oracle、大数据相关的外部项目。其中Oracle相关项目有:Oracle手册文档翻译、多媒体培训等。技术背景涉及数据库、Web、Java等。在XML领域,他因为参与Apache Cocoon中的DB Generator,开源项目DBPrism、DBPrism CMS,基于Oracle JVM Directory的Lucene-Oracle集成方案,Restlet.org项目中的Oracle XDB Restlet Adapter(一个能在基于数据库驻存的JVM内部生成本地REST Web服务的解决方案)等项目或模块的开发而为业界所熟知。

从2006年开始,他参与了Oracle ACE计划,这是Oracle公司官方推出的一个计划,旨在认可和奖励Oracle技术社区中技术娴熟并愿意分享他们的知识和经验的成员为该社区所做的贡献。第1章 ElasticSearch简介

我们希望读者通过阅读本书能获取和拓展关于ElasticSearch的基本知识,并假设读者已经知道如何使用ElasticSearch进行单次或批量索引创建,如何发送请求检索感兴趣的文档,如何使用过滤器缩减检索返回文档的数量,以及使用切面/聚合(faceting/aggregation)机制来计算数据的一些统计量。不过,在接触ElasticSearch提供的各种令人激动的功能之前,仍然希望读者能对Apache Lucene有一个快速了解,因为ElasticSearch使用开源全文检索库Lucene进行索引和搜索,此外,我们还希望读者能了解ElasticSearch的一些基础概念,以及为了加快学习进程,牢记这些基础知识,当然,这并不难掌握。同时,我们也需要确保读者能按ElasticSearch所需要的那样正确理解Lucene。本章主要涵盖以下内容:

·Apache Lucene是什么。

·Lucene的整体架构。

·文本分析过程是如何实现的。

·Apache Lucene的查询语言及其使用方法。

·ElasticSearch的基本概念。

·ElasticSearch内部是如何通信的。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内核库文件,直接在应用程序中使用。1.1.2 Lucene的总体架构

尽管我们可以直接探讨Apache Lucene架构的细节,但有些概念还是需要提前了解,以便更好地理解Lucene的架构,它们包括:

·文档(document):索引与搜索的主要数据载体,它包含一个或多个字段,存放将要写入索引或将从索引搜索出来的数据。

·字段(field):文档的一个片段,它包括两个部分:字段的名称和内容。

·词项(term):搜索时的一个单位,代表文本中的某个词。

·词条(token):词项在字段中的一次出现,包括词项的文本、开始和结束的位移以及类型。

Apache Lucene将写入索引的所有信息组织成一种名为倒排索引(inverted index)的结构。该结构是一种将词项映射到文档的数据结构,其工作方式与传统的关系数据库不同,你大可以认为倒排索引是面向词项而不是面向文档的。接下来我们看看简单的倒排索引是什么样的。例如,我们有一些只包含title字段的文档,如下所示:

·ElasticSearch Server(文档1)

·MasteringElasticSearch(文档2)

·Apache solr 4 Cookbook(文档3)

而索引后的结构示意图如下所示。

正如你所见,每个词项指向该词项所出现过的文档数。这种索引组织方式支持快速有效的搜索操作,例如基于词项的查询。除了词项本身以外,每个词项还有一个与之关联的计数(即文档频率),用来告诉Lucene这个词项在多少个文档中出现过。

当然,实际中Lucene创建的索引更为复杂,也更先进,因为索引中还存储了很多其他信息,如词向量(为单个字段创建的小索引,存储该字段中所有的词条)、各字段的原始信息、文档删除标记等。然而,你只需知道Lucene索引中数据是如何组织的即可,而不用知道到底存储了哪些东西。

每个索引由多个段(segment)组成,每个段只会被创建一次但会被查询多次。索引期间,段经创建就不会再被修改。例如,文档被删除以后,删除信息被单独保存在一个文件中,而段本身并没有修改。

多个段会在一个叫作段合并(segments merge)的阶段被合并在一起,而且要么强制执行,要么由Lucene的内在机制决定在某个时刻执行,合并后段的数量更少,但是更大。段合并非常耗I/O,且合并期间有些不再使用的信息也将被清理掉,例如,被删除的文档。对于容纳相同数据的索引,段的数量较少时,搜索速度更快。尽管如此,还是需要强调一下:因为段合并非常耗I/O,请不要强制进行段合并,你只需要仔细配置段合并策略,剩余的事情Lucene会自行搞定。如果你想知道段由哪些文件组成以及每个文件都存储了什么信息,请参考Apache Lucene的官方文档:http://lucene.apache.org/core/4_5_0/core/org/apache/lucene/codecs/lucene45/package-summary.html。1.1.3 分析你的数据

读者也许会好奇,文档中的数据是如何转化为倒排索引的,而查询串又是如何转换为可用于搜索的词项的?这个转换过程称为分析(analysis)。

文本分析由分析器来执行,而分析器由分词器(tokenizer)、过滤器(filter)和字符映射器组成(character mapper)。

Lucene的分词器用来将文本切割成词条,其中携带各种额外信息的词项,这些信息包括:词项在原始文本中的位置、词项的长度。分词器的工作成果称为词条流,因为这些词条被一个接一个地推送给过滤器处理。

除了分词器,过滤器也是Lucene分析器的组成部分,过滤器数额可选,可以为0个、1个或多个,用于处理词条流中的词条。例如,它可以移除、修改词条流中的词条,甚至可以创造新的词条。Lucene提供了很多现成的过滤器,你也可以根据需要实现新的过滤器。以下是一些过滤器的例子:

·小写过滤器:将所有词条转化为小写。

·ASCII过滤器:移除词条中所有非ASCII字符。

·同义词过滤器:根据同义词规则,将一个词条转化为另一个词条。

·多语言词干还原过滤器:将词条的文本部分归约到它们的词根形式,即词干还原。

当分析器中有多个过滤器时,会逐个处理,理论上可以有无限多个过滤器。

最后我们介绍字符映射器,它用于调用分词器之前的文本预处理操作,如HTML文本的去标签处理。

索引与查询

也许读者会好奇,Lucene以及所有基于Lucene的软件,是如何控制索引和查询操作的。在索引期,Lucene会使用你选择的分析器来处理文档中的内容,并可以对不同的字段使用不同的分析器,例如,文档的title字段与description字段就可以使用不同的分析器。

在检索时,如果使用了某个查询分析器(query parser),那么查询串就会被分析。当然,你也可以选择不进行查询分析。有一点需要牢记,ElasticSearch中有些查询会被分析,而有些则不会。例如,前缀查询(prefix query)不会被分析,而匹配查询(match query)会被分析。

你还应该记住,索引期与检索期的文本分析要采用同样的分析器,只有查询分析出来的词项与索引中词项能匹配上,才会返回预期的文档集。例如,如果在索引期使用了词干还原与小写转换,那么在查询期也应该对查询串做相同的处理,否则查询可能不会返回任何结果。1.1.4 Lucene查询语言

ElasticSearch提供的一些查询类型(query type)支持Apache Lucene的查询解析语法,因此,我们应该深入了解Lucene的查询语言并加以描述。

理解基本概念

在Lucene中,一个查询通常被分割为词项与操作符。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操作符。

另外,你还可以使用圆括号对从句进行分组,以构造更复杂的从句,例如:

在字段中查询

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

也可以在一个字段中同时使用多个从句,例如,要查找所有在title字段中同时包含词项elasticsearch和短语mastering book的文档,可执行如下查询:

当然,该查询也可以写成下面这种形式:

词项修饰符

除了使用简单词项和从句的常规字段查询以外,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节进一步了解什么是权重值,以及它在文档评分中的作用。

我们也可以使用方括号和花括号来构建范围查询。例如,要在一个数值类型的字段上执行一个范围查询,执行如下查询即可:

上述查询所返回文档的price字段的值大于等于10.00并小于等于15.00。

当然,我们也可以在字符串类型的字段上执行范围查询,例如:

上面查询所返回文档的name字段包含按字典顺序介于Adam和Adria之间(包括Adam和Adria)的词项。

如果想执行范围查询同时又想排除边界值,则可使用花括号作为修饰符。例如,查找price字段值大于等于10.00但小于15.00的文档,可使用如下查询:

特殊字符处理

很多应用场景中,需要搜索某个特殊字符(这些特殊字符包括+、-、&&、||、!、(,)、{}、[]、^、"、~、*、?、:、\、/),这时先使用反斜杠对这些特殊字符进行转义。例如,搜索abc"efg这个词项,需要按如下方式处理:1.2 ElasticSearch简介

虽然读者可能已经对ElasticSearch有所了解,至少已经了解了它的一些核心概念和基本用法。然而,为了全面理解该搜索引擎是如何工作的,我们最好简略地讨论一下它。

ElasticSearch是一个可用于构建搜索应用的成品软件"> \2[1]。它最早由Shay Banon创建并于2010年2月发布。之后的几年ElasticSearch迅速流行开来,成为商业解决方案之外且开源的一个重要选择,也是下载量最多的开源软件之一,每月下载量超过20万次。">

[1] 区别于Lucene 这种中间件。——译者注1.2.1 ElasticSearch的基本概念

现在,让我们了解一下ElasticSearch的基本概念及其特征。

索引

ElasticSearch将它的数据存储在一个或多个索引(index)中。用SQL领域的术语来类比,索引就像数据库,可以向索引写入文档或者从索引中读取文档,并通过在ElasticSearch内部使用Lucene将数据写入索引或从索引中检索数据。需要注意的是,ElasticSearch中的索引可能由一个或多个Lucene索引构成,具体细节由ElasticSearch的索引分片(shard)、复制(replica)机制及其配置决定。

文档

文档(document)是ElasticSearch世界中的主要实体(对Lucene来说也是如此)。对所有使用ElasticSearch的案例来说,它们最终都可以归结为对文档的搜索。文档由字段构成,每个字段有它的字段名以及一个或多个字段值(在这种情况下,该字段被称为是多值的,即文档中有多个同名字段)。文档之间可能有各自不同的字段集合,且文档并没有固定的模式或强制的结构。另外,这些规则也适用于Lucene文档。事实上,ElasticSearch的文档最后都存储为Lucene文档了。从客户端的角度来看,文档是一个JSON对象(想了解更多关于JSON格式细节,请参考http://en.wikipedia.org/wiki/JSON)。

映射

正如你在1.1节所了解的那样,所有文档在写入索引前都需要先进行分析。用户可以设置一些参数,来决定如何将输入文本分割为词条,哪些词条应该被过滤掉,或哪些附加处理是有必要被调用的(如移除HTML标签)。此外,ElasticSearch也提供了各种特性,如排序时所需的字段内容信息。这就是映射(mapping)扮演的角色,存储所有这种元信息。虽然ElasticSearch能根据字段值自动检测字段的类型,但有时候(事实上,几乎是所有时候)用户还是想自行配置映射,以避免出现一些令人不愉快的意外。

类型

ElasticSearch中每个文档都有与之对应的类型(type)定义。这允许用户在一个索引中存储多种文档类型,并为不同文档类型提供不同的映射。

节点

单个的ElasticSearch服务实例称为节点(node)。很多时候部署一个ElasticSearch节点就足以应付大多数简单的应用,但是考虑到容错性或在数据膨胀到单机无法应付这些状况时,你也许会更倾向于使用多节点的ElasticSearch集群。

集群

当数据量或查询压力超过单机负载时,需要多个节点来协同处理,所有这些节点组成的系统称为集群(cluster)。集群同时也是无间断提供服务的一种解决方案,即便在某些节点因为宕机或执行管理任务(如升级)不可用时。ElasticSearch几乎无缝集成了集群功能。在我们看来,这是它胜过竞争对手的最主要的优点之一。而且,在ElasticSearch中配置一个集群是再容易不过的事了。

分片

正如我们之前提到的那样,集群允许系统存储的数据总量超过单机容量。为了满足这个需求,ElasticSearch将数据散布到多个物理Lucene索引上。这些Lucene索引称为分片(shard),而散布这些分片的过程叫作分片处理(sharding)。ElasticSearch会自动完成分片处理,并且让这些分片呈现出一个大索引的样子。请记住,除了ElasticSearch本身自动进行分片处理外,用户为具体的应用进行参数调优也是至关重要的,因为分片的数量在索引创建时就已经配置好,而且之后无法改变,至少对目前的版本是这样的。

副本

分片处理允许用户向ElasticSearch集群推送超过单机容量的数据。副本(replica)则解决了访问压力过大时单机无法处理所有请求的问题。思路很简单,即为每个分片创建冗余的副本,处理查询时可以把这些副本用作最初的主分片(primary shard)。请记住,我们并未付出额外的代价。即使某个分片所在的节点宕机,ElasticSearch也可以使用其副本,从而不会造成数据丢失,而且支持在任意时间点添加或移除副本,所以一旦有需要可随时调整副本的数量。

网关

在ElasticSearch的工作过程中,关于集群状态,索引设置的各种信息都会被收集起来,并在网关(gateway)中被持久化。1.2.2 ElasticSearch架构背后的关键概念

ElasticSearch架构遵循了一些设计理念。通常开发团队希望这个搜索引擎产品易于使用和扩展,并能在ElasticSearch的各个地方体现出来。从架构的角度出发,ElasticSearch具有下面这些主要特征:

·合理的默认配置,使得用户在简单安装以后能直接使用ElasticSearch而不需要任何额外的调试,这包括内置的发现(如字段类型检测)和自动配置功能。

·默认的分布式工作模式。每个节点总是假定自己是某个集群的一部分或将是某个集群的一部分,一旦工作启动节点便会加入某个集群。

·对等架构(P2P)可以避免单点故障(SPOF)。节点会自动连接到集群中的其他节点,进行相互的数据交换和监控操作。这其中就包括索引分片的自动复制。

·易于向集群扩充新节点,不论是从数据容量的角度还是数量角度。

·ElasticSearch没有对索引中的数据结构强加任何限制,从而允许用户调整现有的数据模型。正如之前描述的那样,ElasticSearch支持在一个索引中存在多种数据类型,并允许用户调整业务模型,包括处理文档之间的关联(尽管这种功能非常有限)。

·准实时(Near Real Time,NRT)搜索和版本同步(versioning)。考虑到ElasticSearch的分布式特性,查询延迟和节点之间临时的数据不同步是难以避免的。ElasticSearch尝试消除这些问题并且提供额外的机制用于版本同步。1.2.3 ElasticSearch的工作流程

现在,让我们简单地讨论一下ElasticSearch是如何工作的。

启动过程

当ElasticSearch节点启动时,它使用广播技术(也可配置为单播)来发现同一个集群中的其他节点(这里的关键是配置文件中的集群名称)并与它们连接。读者可以通过下图的描述来了解相关的处理过程:

集群中会有一个节点被选为管理节点(master node)。该节点负责集群的状态管理以及在集群拓扑变化时做出反应,分发索引分片至集群的相应节点上。请记住,从用户的角度来看,ElasticSearch中的管理节点并不比其他节点重要,这与其他某些分布式系统不同(如数据库)。实际上,你不需要知道哪个节点是管理节点,所有操作可以发送至任意节点,ElasticSearch内部会自行处理这些不可思议的事情。如果有需要,任意节点可以并行发送子查询给其他节点,并合并搜索结果,然后返回给用户。所有这些操作并不需要经过管理节点处理(请记住,ElasticSearch是基于对等架构的)。

管理节点读取集群的状态信息,并在必要时进行恢复处理。在该阶段,管理节点会检查所有索引分片并决定哪些分片将用于主分片。然后,整个集群进入黄色状态。

这意味着集群可以执行查询,但是系统的吞吐量以及各种可能的状况是未知的(这种状况可以简单理解为所有的主分片已经分配出去了,而副本没有),因而接下来就是要寻找到冗余的分片并用作副本。如果某个主分片的副本数过少,管理节点将决定基于某个主分片创建分片和副本。如果一切顺利,集群将进入绿色状态(这意味着所有主分片和副本均已分配好)。

故障检测

集群正常工作时,管理节点会监控所有可用节点,检查它们是否正在工作。如果任何节点在预定义的超时时间内没有响应,则认为该节点已经断开,然后开始启动错误处理过程。这意味着要在集群-分片之间重新做平衡,因为之前已断开节点上的那些分片不可用了,剩下的节点要肩负起相应的责任。换句话说,对每个丢失的主分片,一个新的主分片将会从原来的主分片的副本中脱颖而出。新分片和副本的放置策略是可配置的,用户可以根据具体需求进行配置。更多信息请参见第4章(索引分布架构)的内容。

为了描述故障检测(failure detection)是如何工作的,我们用一个只有三个节点的集群为例,即包含一个管理节点,两个数据节点。管理节点会发送ping请求至其他节点,然后等待响应。如果没有响应,则该节点会从集群中移除。如下图所示:

与ElasticSearch通信

前面已经讨论过ElasticSearch是如何构建的了,然而,对普通用户来说,最重要的还是如何向ElasticSearch推送数据并构建查询。为了提供这些功能,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进行节点间通信。读者可以在第8章中了解更多Java API的细节,而这里只是简略地了解Java API提供了哪些功能。本书假设读者已经使用过这些功能了,只是在此做一点小小的提示。如果用户还没有使用过,强烈建议阅读相关材料,其中《ElasticSearch Server》一书覆盖了所有这些内容。

索引数据

ElasticSearch提供了四种方式来创建索引。最简单的方式是使用索引API,它允许用户发送一个文档至特定的索引。例如,使用curl工具(详见http://curl.haxx.se/),并用如下命令创建一个文档:

第二种或第三种方式允许用户通过bulk API或UDP bulk API来一次性发送多个文档至集群。两者的区别在于网络连接方式,前者使用HTTP协议,后者使用UDP协议,且后者速度快,但是不可靠。第四种方式使用插件发送数据,称为河流(river),河流运行在ElasticSearch节点上,能够从外部系统获取数据。

有一件事情需要记住,建索引操作只会发生在主分片上,而不是副本上。当把一个索引请求发送至某节点时,如果该节点没有对应的主分片或者只有副本,那么这个请求会被转发到拥有正确的主分片的节点(如下图所示)。

查询数据

查询API占据了ElasticSearch API的大部分内容。使用查询DSL(基于JSON的可用于构建复杂查询的语言),我们可以做下面这些事情:

·使用各种查询类型,包括:简单的词项查询、短语查询、范围查询、布尔查询、模糊查询、区间查询、通配符查询、空间查询等。

·组合简单查询构建复杂查询。

·文档过滤,在不影响评分的前提下抛弃那些不满足特定查询条件的文档。

·查找与特定文档相似的文档。

·查找特定短语的查询建议和拼写检查。

·使用切面构建动态导航和计算各种统计量。

·使用预搜索(prospective search)并查找与指定文档匹配的query集合。

对于查询操作,读者应该要重点了解:查询并不是一个简单的、单步骤的操作。一般来说,查询分为两个阶段:分散阶段(scatter phase)和合并阶段(gather phase)。分散阶段将query分发到包含相关文档的多个分片中去执行查询,合并阶段则从众多分片中收集返回结果,然后对它们进行合并、排序、后续处理,然后返回给客户端。该机制可以由下图描述。ElasticSearch对外提供了6个系统参数,任何一个都可以用来定制分散/合并机制。关于这个问题可参阅本书的上一版《ElasticSearch Server》(Packt出版社)。

索引配置

前面已经讨论过ElasticSearch的自动索引配置以及发现识别文档字段类型和结构的功能。当然,ElasticSearch也提供了一些功能使得用户能手动配置,例如用户想通过映射来配置自定义的文档结构,或者想设置索引的分片和副本数,抑或定制文本分析过程,种种这些需求都可以通过手动配置解决。

系统管理和监控

ElasticSearch中系统管理和监控相关的API允许用户改变集群的设置,如调节集群发现机制和索引放置策略等。此外,你还可得到关于集群状态信息或每个节点、每个索引的统计信息。集群监控API非常全面,我们将在第5章学习相关API的使用范例。1.3 小结

在本章中,我们了解了Apache Lucene的一般架构,例如它的工作原理,文本分析过程是如何完成的,如何使用Apache Lucene查询语言。此外,我们还讨论了ElasticSearch的一些基本概念,例如它的基本架构和内部通讯机制。

在下一章,我们将学习Apache Lucene的默认评分公式,什么是查询重写过程(query rewrite process)以及它是如何工作的。除此之外,还将讨论ElasticSearch的一些功能,例如查询的二次评分(query rescore)、准实时批量获取(multi near real-time get)、批量搜索操作(bulk search operations)。接着将学习到如何使用update API来部分地改变文档,如何对数据进行排序,如何使用过滤功能(filterring)来改进查询的性能。最后,我们将了解如何在切面机制中使用过滤器(filters)和作用域(scope)。第2章 查询DSL进阶

上一章我们了解了什么是Apache Lucene,它的整体架构,以及文本分析过程是如何完成的。之后,我们介绍了Lucene的查询语言及其用法。除此之外,我们还讨论了ElasticSearch及其架构和一些核心概念。在本章,我们将深入研究ElasticSearch的查询DSL(Domain Specific Language)。然而,在了解那些高级查询之前,我们先来了解Lucene评分公式的工作原理。本章将涵盖以下内容:

·Lucene默认评分公式是如何工作的。

·什么是查询重写。

·查询二次评分是如何工作的。

·如何在单次请求中实现批量准实时读取操作。

·如何在单次请求中发送多个查询。

·如何对包括嵌套文档和多值字段的数据排序。

·如何更新已索引的文档。

·如何通过使用过滤器来优化查询。

·如何在ElasticSearch的切面计算机制中使用过滤器和作用域。2.1 Apache Lucene默认评分公式解释

对于查询相关性,重点是去理解文档对查询的得分是如何计算出来的。什么是文档得分?它是一个刻画文档与查询匹配程度的参数。本节我们就将了解Apache Lucene的默认评分机制:TF/IDF(词频/逆文档频率)算法以及它是如何影响文档召回的。了解评分公式的工作原理对构造复杂查询以及分析查询中因子的重要性都是很有价值的。2.1.1 何时文档被匹配上

当一个文档经Lucene返回,则意味着该文档与用户提交的查询是匹配的。在这种情况下,每个返回的文档都有一个得分。得分越高,文档相关度更高,至少从Apache Lucene及其评分公式的角度来看是这样的。显而易见,同一个文档针对不同查询的得分是不同的,而且比较某文档在不同查询中的得分是没有意义的。读者需要注意,同一文档在不同查询中的得分不具备可比较性,不同查询返回文档中的最高得分也不具备可比较性。这是因为文档得分依赖多个因子,除了权重和查询本身的结构,还包括匹配的词项数目,词项所在字段,以及用于查询规范化的匹配类型等。在一些比较极端的情况下,同一个文档在相似查询中的得分非常悬殊,仅仅是因为使用了自定义得分查询或者命中词项数发生了急剧变化。

现在,让我们再回到评分过程。为了计算文档得分,需要考虑以下这些因子:

·文档权重(document boost):索引期赋予某个文档的权重值。

·字段权重(field boost):查询期赋予某个字段的权重值。

·协调因子(coord):基于文档中词项命中个数的协调因子,一个文档命中了查询中的词项越多,得分越高。

·逆文档频率(inverse document frequency):一个基于词项的因子,用来告诉评分公式该词项有多么罕见。逆文档频率越低,词项越罕见。评分公式利用该因子为包含罕见词项的文档加权。

·长度范数(length norm):每个字段的基于词项个数的归一化因子(在索引期计算出来并存储在索引中)。一个字段包含的词项数越多,该因子的权重越低,这意味着Apache Lucene评分公式更“喜欢”包含更少词项的字段。

·词频(term frequency):一个基于词项的因子,用来表示一个词项在某个文档中出现了多少次。词频越高,文档得分越高。

·查询范数(query norm):一个基于查询的归一化因子,它等于查询中词项的权重平方和。查询范数使不同查询的得分能相互比较,尽管这种比较通常是困难且不可行的。2.1.2 TF/IDF评分公式

现在我们来看评分公式。请记住,为了调节查询相关性,你并不需要深入理解这个公式的来龙去脉,但是了解它的工作原理是非常重要的。

Lucene理论评分公式

TF/IDF公式的理论形式如下:

上面的公式糅合了布尔检索模型和向量空间检索模型。现在,我们并不讨论理论评分公式,而是直接跳到Lucene实际评分公式,因为在Lucene内部就是这么实现并使用的。关于布尔检索模型和向量空间检索模型的知识远远超出了本书的讨论范围,想了解更多相关知识,请参考http://en.wikip-edia.org/wiki/Vector_Space_Model。

Lucene实际评分公式

现在让我们看看Lucene实际使用的评分公式:

也许你已经看到了,得分公式是一个关于查询q和文档d的函数,有两个因子coord和queryNorm并不直接依赖查询词项,而是与查询词项的一个求和公式相乘。

求和公式中每个加数由以下因子连乘所得:词频、逆文档频率、词项权重、范数。范数就是之前提到的长度范数。

这个公式听起来很复杂。请别担心,你并不用记住所有的细节,而只需意识到哪些因素是跟评分有关即可。从前面的公式我们可以导出一些基本规则:

·越多罕见的词项被匹配上,文档得分越高。

·文档字段越短(包含更少的词项),文档得分越高。

·权重越高(不论是索引期还是查询期赋予的权重值),文档得分越高。

正如你所见,Lucene将最高得分赋予同时满足以下条件的文档:包含多个罕见词项,词项所在字段较短(该字段索引了较少的词项)。该公式更“喜欢”包含罕见词项的文档。如果你想了解更多关于Apache Lucene TF/IDF评分公式的信息,请参考Apache lucene中TFIDFSimilarity类的文档:http://lucene.apache.org/core/4_5_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html。2.1.3 ElasticSearch如何看评分

总而言之,是ElasticSearch使用了Lucene的评分功能,但好在我们可以替换默认的评分算法(更多细节请参考3.1节)。还有一点请记住,ElasticSearch使用了Lucene的评分功能但不仅限于Lucene的评分功能。用户可以使用各种不同的查询类型以精确控制文档评分的计算(如custom_boost_factor查询、constant_score查询、custom_score查询等),还可以通过使用脚本(scripting)来改变文档得分,还可以使用ElasticSearch 0.90中出现的二次评分功能,通过在返回文档集之上执行另外一个查询,重新计算前N个文档的文档得分。想了解更多Apache Lucene查询类型,请参考http://lucene.apache.org/core/4_5_0/queries/org/apache/lucene/queries/package-summary.html上的相关文档。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载