本章主要内容
如今,我们无处不在地使用“搜索”。这是件好事,因为搜索能帮你从容不迫地完成手头上的工作。无论是在线购物,还是访问博客,你都不会心甘情愿地将整个站点翻个底朝天,而是更希望有个搜索框适时地出现,帮助你发现真心想要的。也许只有我是这样的人,当我(Radu)在清晨醒来的时候,多么希望进入厨房后,能有个搜索框让人可以直接输入“碗”这个词,然后最心爱的碗就出现在面前。
我们也很期待这些搜索框变得更智能。没有必要输入“碗”这个词所需的全部字母(要知道,在英文里bowl要输入4个字母);希望搜索框能有自动提示的功能,而且提示的内容要合理,不能胡乱提示。搜索返回的内容也要智能些,最相关的结果要排在前面:简单来说就是尽可能猜中用户想要什么。举个例子,在线购物时,我搜索了“笔记本电脑”,发现排在前面的都是笔记本的配件,往下翻了很多才看到真正的电脑,那看完这页后我一定会去其他家买了。我们需要看到最相关的结果和提示,一方面是因为人们生活节奏很快,被许多良好的搜索体验宠坏后不愿意再浪费时间;另一个方面,有越来越多的东西可供选择。再举个例子,一位朋友让我帮她挑台新的笔记本电脑。如果查询“为我的朋友购买一台最棒的笔记本电脑”,那么一家在线商店即使销售成千上万款别致的电脑,它也不太可能给出有效的答案。良好的关键字查询往往还不够,你还需要从搜索结果中得到一些统计信息,并利用其定位用户的兴趣。我会选择屏幕的尺寸、价格区间等来逐步缩小选择的范围,直到将目标锁定到5台左右的电脑。
最后,还需要考虑性能问题,因为没有人愿意等待。我曾经在一些网站上有过糟糕的经历,搜索过后数分钟结果才展现出来。注意,单位是分钟!一次搜索竟然花了这么久。
如果你想让自己的数据能被搜索,需要处理如下事项:返回相关的搜索结果,返回统计信息,而且要非常快速地完成。这就是Elasticsearch这种搜索引擎存在的意义,因为它们生来就是迎接这些挑战的。它可以在关系型数据库上搭建搜索引擎,建立索引并加速SQL查询的执行。或许,也可以从NoSQL数据存储上建立索引,然后支持搜索功能。可以通过Elasticsearch做到这些,此外由于Elasticsearch里的数据是通过文档形式表示的,它和MongoDB这种面向文档的存储搭配起来也很美妙。Elasticsearch这样的现代搜索引擎还能完好地存储数据,甚至可以将其直接作为带搜索功能的NoSQL数据存储来使用。
Elasticsearch是构建在Apache Lucene之上的开源分布式搜索引擎。Lucene是开源的搜索引擎包,允许你通过自己的Java应用程序实现搜索功能。Elasticsearch充分利用Lucene,并对其进行了扩展,使存储、索引、搜索都变得更快、更容易,而最重要的是,正如名字中的“elastic”所示,一切都是灵活、有弹性的。而且,应用代码也不是必须用Java书写才可以和Elasticsearch兼容,你完全可以通过JSON格式的HTTP请求来进行索引、搜索和管理Elasticsearch集群。
本章将阐述搜索和数据的特性,你将在本书中学习如何使用它们。首先,让我们来近距离体验一下搜索引擎通常面临的挑战,以及Elasticsearch应对这些挑战的解决方案吧。
为了更好地理解Elasticsearch是如何工作的,让我们先看一个示例。假设你正在搭建一个博客网站,并且希望用户可以在全站搜索特定的帖子。要完成的第一项任务就是实现基于关键词的搜索。例如,一位用户查询“选举”,系统需要返回所有包含这个关键词的帖子。
搜索引擎将完成这些工作,但是对于一个健壮 的搜索功能而言,你需要更多特性:引擎可以快速地返回查询结果,而且这些结果都是相关的。当用户并不清楚具体要用哪些词来查找时,搜索还能提供辅助的功能,用于实现更佳的用户体验。这些辅助的功能具体包括识别错误的输入,给出自动提示,并对结果进行分类。
提示
本章的大部分内容将有助于你了解Elasticsearch的特性。如果你是个急性子,迫不及待想实战一把,并准备安装它了,可以直接跳到1.5节。你会发现原来安装如此之简单。当然,也可以随时回到这里,看看整体的概述。
如果网站上有很多帖子,在其中查找“选举”这个词会非常耗时。你当然不希望用户一直等着。Elasticsearch恰好能帮上忙,因为它是采用Lucene作为底层的。Lucene是个高性能的搜索引擎包,默认情况下会将所有的数据全部进行索引。
这里所说的索引 是一种数据结构,它依据你的数据建造,最终会让搜索变得非常迅速。在大多数据库中,可以使用几种不同的方式为字段添加索引。而Lucene使用的是倒排索引,这意味着它将创建一个数据结构,并在其中保存记录每个单词出现在哪些数据中的清单。例如,如果你想按照标签来搜索博客文章,倒排索引看上去就会如表1-1所示。
表1-1 博客标签的倒排索引
原始数据 | 索引数据(倒排索引) | ||
---|---|---|---|
博客文章ID | 标签 | 标签 | 博客文章ID |
1 |
elections |
elections |
1 ,3 |
2 |
peace |
peace |
2 ,3 ,4 |
3 |
elections ,peace |
||
4 |
peace |
如果搜索含有elections(
选举)标签的帖子,那么相对查找原始数据而言,查找倒排索引后的数据会更快捷。因为只需要查看标签是elections
这一栏,然后获得相应所有的文章ID(这里是1和3)。在搜索引擎的应用场景下,这种速度的提升是非常必要的。在现实世界中,你基本不会只查询1个关键词。例如,如果搜“Elasticsearch in Action”,3个词就意味着查询速度提升了3倍。现在看来这有点儿晦涩难懂,不过没关系,在第3章讨论建立索引和第4章讨论搜索时,我们将解释更多的细节。
即使考虑到相关性,倒排索引对于搜索引擎而言也是一个适合的方案。举个例子,当查找“peace”(和平)这样的单词时,你不仅可以看到哪些文档是匹配的,还能免费获得这些文档的总数。这一点很关键,原因是一个词如果出现在很多文档中,那么它很可能和每个文档都不太相关了。就说搜索的“Elasticsearch in Action”吧,有个文档包括“in”这个单词(当然还有上百万个文档也包括“in”)。你会意识到“in”是个常见词,即使这个文档因为包含“in”而匹配成功,也不代表它和查询有多相关。对比之下,如果这个文档包含“Elasticsearch”(可能还有数百个文档也包含“Elasticsearch”),你就知道离相关文档不远了。其实,知道离答案更进一步的并不是“你”,而是Elasticsearch替你完成了。在第6章中,读者将会学到如何通过调优数据和搜索来提升相关性。
同时,为了提升搜索的性能和相关性,还需要更多的磁盘空间来存储索引。增加新的博客帖子会越来越慢,因为每次添加数据就要更新索引。对此,调优可以让Elasticsearch无论在索引还是搜索时都变得更快。我们将在第10章详细讨论这些细节。
接下来有一个难题:如何将真正描述选举的帖子排序在前呢?有了Elasticsearch,就可以使用几个算法来计算相关性的得分(relevancy score) ,然后根据分数来将结果逐个排序。
对于每个符合查询条件的文档,它的相关性得分标示该文档和查询条件的相关程度。例如,一条博客帖子多次出现了“elections”,频率超过了其他的帖子,那么该文章讨论选举相关的话题的可能性就更大。这里我们看下DuckDuckGo的示例,如图1-1所示。
图1-1 如果文档出现更多的查询关键词(加粗的那些),它就会拥有靠前的排名
默认情况下,计算文档相关性得分的算法是TF-IDF(term frequency-inverse document frequency,词频-逆文档频率)。我们将在讨论搜索和相关性的第4章和第6章中,进一步讨论得分和TF-IDF的更多细节。这里先讲一下基本概念——TF-IDF,下面是会影响相关性得分的两个因素。
例如,当在自行车爱好者的博客上搜索“自行车竞赛”的时候,因为“自行车”在所有文档中出现的频率要高于“竞赛”,所以对最后得分贡献较小。同时,一篇文章中二者出现次数越多,这篇文章的得分也会越高。
除了选择算法,Elasticsearch还提供了很多其他内置的功能来计算相关性得分,以满足定制需求。例如,你可以“提升”特定字段的得分:从相关性的角度考虑,帖子的标题比文章主体更为重要。这样标题上相匹配的文档会比仅仅在主体中匹配上的文档获得更高的分数。你也可以让精确匹配比部分匹配获得更高的分数,甚至通过脚本添加定制条件来改变得分的计算。例如,如果帖子允许用户点赞,可以根据点赞数来提升得分,或者让新的帖子获得更高得分,排在较旧的帖子之前。
现在不用担心这些特性的具体机制。第6章中会讨论更多相关性的细节。当下,让我们重点关注通过Elasticsearch能做什么,以及何时会用到这些特性。
最后,Elasticsearch有些选项可以让搜索变得很直观,而不仅仅是精确匹配用户的输入。当用户录入与已存储词有所不同的错误拼写、同义词或派生词时,这些选项使用起来非常方便。当用户不完全清楚搜索什么的时候,这些选项也能帮到他们。
可以通过配置,让Elasticsearch容忍一些变化,而不仅仅是只查找精确匹配。使用模糊查询,“bicycel”的输入同样可以让用户找到关于“bicycles”的博客。在第6章中,我们将会深入研究模糊查询和其他相关性的特性。
使用第5章中阐述的分析模块可以让Elasticsearch明白这个道理:标题里包含“bicycle”的帖子,同样可以和“bicyclist”或“cycling”的查询匹配上。你可能已经注意到,在图1-1中,“elections”同样会匹配“election”。你还会注意到,匹配的单词会通过加粗来突显。Elasticsearch同样可以实现这个功能,在附录C中将讨论高亮功能。
当用户不太清楚具体要搜索什么的时候,可以通过几种方式来协助他们。一种方法是第7章探讨的聚集统计数据。聚集是在搜索结果里得到一些统计数据,如每个分类有多少议题、每个分类中“赞”和“分享”的平均数量。假想一下,进入博客时,用户会在右侧看见最近流行的议题。其中之一是自行车。对其感兴趣的读者会点击这个标题,进一步缩小范围。然后,可能还有另外的聚集方式,将自行车相关的帖子分为“自行车鉴赏”“自行车大事件”等。
当用户开始输入时,你可以帮助他们发现主流的查询和结果。还可以通过自动提示技术预测他们所要输入的内容,就像Web上很多搜索引擎做的那样。你同样可以展示主流的结果,通过特殊的查询类型来匹配前缀、通配符或正则表达式。附录F中会讨论建议器(suggester),与普通的查询自动完成功能相比,建议器速度更快。
既然已经讨论了Elasticsearch的整体功能,接下来就来看看在实际产品中这些功能是如何使用的。
我们已经可以确定,在Elasticsearch中存储和索引数据,是提供快速和相关查询结果的上佳方法。但是归根结底,Elasticsearch只是个搜索引擎,你永远不可能单独使用它。就像其他数据存储,需要通过某种方式将数据输入到其中,也可能需要提供用户搜索数据的交互界面。
为了理解Elasticsearch是如何融入更大的系统中的,来考虑以下3种典型的应用场景。
让我们仔细查看一下每个应用场景。
传统意义上说来,搜索引擎在完善的数据存储的基础之上部署,用于提供快速和相关的搜索能力。这是因为历史上的搜索引擎没有提供持久化存储以及类似统计的其他常用功能。
Elasticsearch是一个现代搜索引擎,提供了持久化存储、统计和很多其他数据存储的特性。如果正在启动一个新项目,我们建议你考虑使用Elasticsearch作为唯一的数据存储,尽量使设计保持简洁。这样做也许不能在所有用例中都行得通,例如,存在很多数据更新的时候。这时你也可以在另一个数据存储上使用Elasticsearch。
注意
就像其他的NoSQL数据存储,Elasticsearch并不支持事务。在第3章中,你将看到如何使用版本控制来管理并发。如果需要事务机制,请考虑使用其他的数据库作为“真实之源”。另外,在使用单一的数据源时,定期的备份也是很好的实践,我们将在第11章中探讨备份机制。
回到博客的示例:你可以在Elasticsearch中存储新写的博客帖。类似地,可以使用Elasticsearch来检索、搜索或者在所有数据上进行统计,如图1-2所示。
图1-2 Elasticsearch作为唯一的后端,存储并索引所有的数据
如果一台服务器宕机了会发生什么?可以通过将数据复制到不同的服务器来达到容错的效果。很多其他特性使得Elasticsearch成为一个很有吸引力的NoSQL数据存储。这样做不可能面面俱到,但是你需要权衡一下,在整体设计中引入另一个数据源而增加额外的复杂度,这样做是否值得。
就其本身而言,Elasticsearch也许不会提供你所需的一切数据存储功能。某些场合需要在另一个数据存储的基础上使用Elasticsearch。
例如,目前Elasticsearch还不支持事务和复杂关系的特性,至少在版本1中是如此。如果需要那样的特性,请考虑同时使用Elasticsearch和另一个不同的数据存储。
或者你已经有一个复杂的系统在运作,但是想加入搜索功能。如果只是为了使用Elasticsearch而重新设计整个系统(尽管随着时间的推移你可能有这种想法),那么未免太冒险了。更安全的方法是在系统中加入Elasticsearch,让它和现有模块协同工作。
无论哪种方式,如果你有两个数据存储,必须想方设法保持它们的同步。根据主要数据存储是什么类型的,以及数据是如何布局规划的,可以部署一个Elasticsearch插件,保持两者同步,如图1-3所示。
图1-3 Elasticsearch和另一个数据存储位于同一系统中
举个例子,假设有一家在线零售商店,商品的信息都存在SQL数据库中,需要快速而且相关性良好的搜索,于是安装了Elasticsearch。为了索引数据,需要部署同步的机制,既可以是Elasticsearch的插件,也可以是自行构建的定制化服务。在附录B中你将学习更多关于插件的内容,在第3章中将学习更多通过自己的应用程序进行索引和更新的内容。同步的机制可以将每个商品对应的数据拉取出来,并将其索引到Elasticsearch之中,每个商品存储为一篇Elasticsearch的文档。
当用户在页面上的搜索条件框中输入时,商店的前端网络应用程序根据那些条件查询Elasticsearch。Elasticsearch返回一些符合条件的商品文档,按照你喜欢的方式排序。排序可以基于相关性得分,该得分体现用户查询的关键词在每个商品文档出现的次数,或者是商品文档里存储的任何信息,如商品最近多久上架的、平均的得分甚至是多项因素的综合。
信息的插入或更新仍然可以在“主”SQL数据库上进行,所以你可以使用Elasticsearch仅来处理搜索。保持Elasticsearch更新最近的变化取决于同步的机制。
当需要将Elasticsearch和其他模块集成的时候,可以看看现有的工具哪些已经完成你所想要的。下一部分中将探讨,社区为Elasticsearch构建了一些强大的工具,有些时候没有必要自己构建定制的模块。
在某些用例中,无须编写任何代码,就能让Elasticsearch帮你将任务搞定。很多现成的工具可以和Elasticsearch协同工作,没有必要从头开始。
例如,假设你想部署大规模的日志框架,用于存储、搜索和分析海量的事件。如图1-4所示,为了处理日志,并输出到Elasticsearch,可以使用Rsyslog、Logstash或Apache Flume这样的日志工具。为了通过可视化界面搜索和分析日志,可以使用Kibana。
图1-4 Elasticsearch和另一个数据存储位于同一系统中
事实上,Elasticsearch在Apache 2许可证下是开源的。确切地说,开源不是如此多工具支持Elasticsearch的唯一原因。尽管Elasticsearch是Java编写的,不仅仅是Java API可以和它工作。它也暴露了REST API,任何应用程序,无论是何种编程语言编写的,都可以访问这种接口。
此外,REST请求和结果返回通常是JSON(JavaScript Object Notation)格式的。通常,一个REST请求有其自己的JSON有效载荷,返回结果同样是一个JSON文档。
JSON和YAML
JSON是表达数据结构的一种格式。一个JSON对象通常包含键和值,值可以是字符串、数字、真/假、空、另一个对象或数组。
对于应用程序而言,JSON很容易解析和生成。YAML(YAML Ain’t Markup Language)可以达到同样的目的。为了激活YAML,在HTTP请求中添加
format=yaml
的参数。尽管JSON通常是用于HTTP连接,配置文件常常是以YAML书写。在这本书中,我们坚持使用流行的格式:HTTP连接使用JSON,配置文件使用YAML。
举个例子,在Elasticsearch中进行索引时,一条日志事件可能是这样的:
{
"message": "logging to Elasticsearch for the first time", ←---一个拥有字符串值的字段
"timestamp": "2013-08-05T10:34:00" ←---字符串值可以是一个日期,Elasticsearch会自动评估
}
注意
在全书中,JSON字段名称显示为深灰色,它们的值显示为浅灰色,以此使得代码更容易阅读。
一个message
值为first
的日志搜索请求会是这样:
{
"query": {
"match": { ←---query 字段的值是一个包含match 字段的对象
"message": "first" ←---match 字段包含另一个对象,该对象中message 字段的值是first
}
}
}
通过HTTP上的JSON对象来发送数据、运行查询,这样可以更容易地扩展任何事物,从Rsyslog这样的系统日志守护进程到Apache ManifoldCF这样的连接框架,让它们和Elasticsearch进行交互。如果从头开始构建一个新的应用,或是将搜索功能加入现有的应用,REST API是一个使得Elasticsearch变得更吸引人的特性。我们将在下一部分中了解这些特性。
Elasticsearch让你可以轻松地使用Lucene的索引功能,并搜索数据。在索引步骤中,有许多的选项,可以设置如何处理文本、如何存储处理后的文本。在搜索的时候,有很多查询和过滤器供选择。Elasticsearch通过REST API显露了很多功能,让用户可以构建JSON格式的查询、调整大多数的配置。
在Lucene提供的功能之上,Elasticsearch添加了其自己的高级功能,从缓存到实时性分析。在第7章中,你将学习如何通过聚集功能进行分析,借此获得最流行的博客标签、一组帖子的平均流行度,以及任意的组合,如每类标签中帖子的平均流行度。
另一种抽象层次是组织文档的方式:多个索引可以单独搜索、也可以同时搜索,还可以将不同类型的文档放入不同的索引。
最终,Elasticsearch就像它的名字一样,是具有灵活性的。默认它就是集群化的(即使是在单台服务器上运行,也称之为集群),并且总是可以添加更多的服务器用于增加容量或容错性。类似地,如果负载较低的时候,可以很容易地从集群中移除服务器,降低成本。
在本书余下的部分,我们将讨论这些特性的大量细节(特别是第9章的扩展),在此之前,先来近距离观察下这些特性是如何起到作用的。
在很多用例中,用户会基于多项条件进行搜索。例如,可以在多个字段中搜索多个关键词;一些条件是必需的,一些条件是可选的。Elasticsearch最为人赏识的一个特性是结构合理的REST API:可以通过JSON构建查询,使用很多方式来结合不同类型的查询。在第4章中我们将展示如何做到这些,读者还将理解如何使用过滤器,以低成本和可缓存的方式去包含和排除搜索结果。基于JSON的搜索可以同时包含查询、过滤器和聚集,聚集从匹配的文档中生成统计数据。
通过同样的REST API,可以读取和改变很多设置(将在第11章介绍),包括文档索引的方式。
什么是Apache Solr
如果你已经听说过Lucene,那么可能你也听说了Solr,它是开源的基于Lucene的分布式搜索引擎。实际上,Lucene和Solr于2010年合并为一个单独的Apache项目,你可能好奇Elasticsearch和Solr两者相比孰优孰劣。
两者都提供了相似的功能,每个新版本中特性都快速地进化。可以通过互联网查找它们的对比,但是我们建议持保留态度。除了受限于特定版本(这种比较几个月之内就会过时),很多观点出于种种原因也都是有所偏见的。
即便如此,还是有一些历史事实有助于解释两个产品的起源。Solr诞生于2004年,而Elasticsearch诞生于2010年。当Elasticsearch出现的时候,它采用的分布式模式(本章稍后介绍)使它相比其竞争对手而言更容易水平扩展,这也印证了它名字中的“elastic”。但是,Solr与此同时在版本4.0中加入了分片,因而“分布式”的说法值得商榷,就像很多其他方面一样。
在本书撰写的时候,Elasticsearch和Solr都拥有对方所不具备的特性,对于它们的选择取决于在特定时期所需要的具体功能。对于很多用例而言,你所需的功能两者都已提供。和很多竞品选择一样,它们之间的选择往往变成了个人口味问题。如果想阅读更多关于Solr的内容,我们推荐Trey Grainger和Timothy Potter所著的《Solr实战》(Manning,2014)。
当考虑文档索引的方式时,一个重要的方面是分析。通过分析 ,被索引文本中的单词变为Elasticsearch中的词条。例如,如果索引文本“bicycle race”,分析步骤将产生“bicycle”“race”“cycling”和“racing”的词条。当搜索其中任一词条,相应的文档就会被返回。当进行搜索时,会应用同样的分析过程,如图1-5所示。如果输入“bicycle race”,你可能不想仅仅是字符串的严格匹配。也许某个文档,在不同的位置分别出现这两个关键词,它也是符合要求的。
图1-5 在你进行索引和搜索的时候,分析步骤将文本拆解为单词
默认的分析器首先通过空格和逗号这样的常用单词分隔符,将文本拆解为单词。然后将其转化为小写,这样“Bicycle Race”变为“bicycle”和“race”。有很多分析器供选择,你也可以自行构建。第5章将讨论这些。
目前,图1-5中“被索引的数据”方框看上去非常抽象,你可能想知道其中有些什么。正如接下来所探讨的,数据以文档的形式组织。默认情况下,Elasticsearch原封不动地保存文档,并将分析出的词条放入倒排索引,使得所有重要、快速且相关性良好的搜索成为可能。在第3章中,我们深入数据索引和存储的细节。现在,先来近距离观察一下,为什么Elasticsearch是面向文档的,它又是如何将文档按照类型和索引来组织的。
关系型数据库以记录和行的形式存储数据。和关系型数据库不同,Elasticsearch以文档的形式存储数据。然而,某种程度上说,两个概念是相似的。关系型数据表的行都有很多列,每一行的每一列拥有一个值。每个文档拥有键和值,方式差不多。
区别在于,至少在Elasticsearch中,文档比数据表的行更为灵活。这主要是因为文档可以是具有层次型的。例如,"author":"Joe"
这样的键和字符串值关联方式,同样可以用于文档中关联字符串数组,如"tags ":["cycling", "bicycles"]
,甚至是键值对,如"author": {"first_name":"Joe", "last_name":"Smith"}
。这种灵活性是非常重要的,因为它鼓励你将所有属于一个逻辑实体的数据保持在同一个文档中,而不是让它们散落在不同的数据表的不同行中。例如,最容易的(可能也是最快的)博客文章存储方式是将某篇帖子的所有数据保持在同一个文档中。使用这种方式,搜索是很快速的,因为无须进行表的连接或其他关系型的工作。
如果你有SQL的知识背景,可能会怀念表连接的功能。但至少1.76版本的Elasticsearch中是不支持此项功能的。不过,即使新增了这个功能,通常只需要下载最新版,就能让Elasticsearch再次运行起来。
如果还没有Java Runtime Environment(JRE),需要先安装它。任何1.7或更新版本的JRE都是可以的。通常,人们会安装从Oracle下载的版本,或者是开源的实现版OpenJDK。
“没有发现Java”错误的排除
在Elasticsearch或其他Java应用程序中,可能会发生这样的情况:你已经下载并安装了Java,但是应用程序没能启动,并提示无法发现Java。
Elasticsearch的脚本通过两种方式查找Java的安装:
JAVA_HOME
环境变量和系统路径。要检查Java安装目录是否在JAVA_HOME
中,在UNIX类系统中使用env
命令,在Windows系统中使用set
命令。要检查是否在系统路径中,运行如下命令:% java -version
。如果生效了,那么Java就已经配置在路径之中。如果不行,要么配置
JAVA_HOME
,要么将Java运行包添加到路径中。Java的运行包通常在Java安装路径(应该就是JAVA_HOME
)的bin
目录中。
当Java设置完毕,需要获得Elasticsearch并启动它。请下载最适合你工作环境的安装包。在Elastic官方网站上可用的安装包选项有Tar、ZIP、RPM和DEB。
如果在Linux、Mac或其他任何UNIX类的操作系统上运行,可以从tar.gz包获得Elasticsearch。然后将安装包展开,通过压缩包中的shell脚本来启动Elasticsearch。
% tar zxf elasticsearch-*.tar.gz
% cd elasticsearch-*
% bin/elasticsearch
如果需要在Mac上使用更简单的方式来安装Elasticsearch,可以安装Homebrew。Homebrew 安装完毕运行如下命令就可以获得Elasticsearch:
% brew install elasticsearch
然后,使用和tar.gz压缩包类似的方式开始启动Elasticsearch:
% elasticsearch
如果是在Windows上运行,请下载ZIP压缩包。解压后,和在UNIX上运行Elasticsearch差不多,运行bin/目录中的elasticsearch.bat:
% bin\elasticsearch.bat
如果是在Red Hat Linux、CentOS、SUSE或任何可以读取RPM包的系统上运行,在Debian、Ubuntu或任何可以读取DEB包的系统上运行,Elastic同样也提供RPM和DEB包。你可以在www.elastic.co/guide/en/elasticsearch/reference/current/setup-repositories.html学习如何使用它们。
安装的过程基本上需要将安装包加入你的列表中,并运行安装命令。一旦Elasticsearch安装完成,可以通过如下命令启动它:
% systemctl start elasticsearch.service
如果操作系统没有systemd软件,请使用:
% /etc/init.d/elasticsearch start
如果想知道启动后Elasticsearch在干什么,请查看/var/log/elasticsearch/目录中的日志文件。如果是通过解压TAR或ZIP压缩包来安装的,你应该在解压的logs/目录中可以找到日志文件。
现在已经安装并启动了Elasticsearch,我们来看看启动过程中产生的日志,并首次连接REST API。
在首次运行Elasticsearch的时候,用户会看到一系列日志条目,告诉用户发生了什么。来看看其中的几行意味着什么。
第一行通常提供了启动节点的统计信息:
[node] [Karkas] version[1.4.0], pid[6011], build[bc94bd8/2014-11-05T14:26:12Z]
默认情况下,Elasticsearch为节点随机分配一个名字,在这个例子中是Karkas
,可以在配置中修改。此行还可以看见所运行的特定Elasticsearch版本号细节,然后是所启动的Java进程PID。
插件在初始化过程中被加载,默认情况下是没有插件的。
[plugins] [Karkas] loaded [], sites []
关于插件的更多信息,请参见附录B。
端口9300默认用于节点之间的通信,称为transport:
[transport] [Karkas] bound_address {inet[/0.0.0.0:9300]}, publish_address
{inet[/192.168.1.8:9300]}
如果使用本地Java API而不是REST API,需要连接这个端口。
在下一行,主节点 被选举出来,正是名为Karkas
的节点:
[cluster.service] [Karkas] new_master [Karkas][YPHC_vWiQVuSX-ZIJIlMhg][inet[/
192.168.1.8:9300]], reason: zen-disco-join (elected_as_master)
第9章涵盖了水平扩展的内容,我们在第9章讨论主节点的选举。基本的想法是每个集群拥有一个主节点,负责了解集群中有哪些节点以及分片位于哪里。每当主节点失联,就会选举一个新的主节点。这个例子中,你启动了集群中的第一个节点,所以它也是主节点。
端口9200默认用于HTTP的通信。应用程序使用REST API时连接这个端口:
[http] [Karkas] bound_address {inet[/0.0.0.0:9200]}, publish_address {inet[/
192.168.1.8:9200]}
下面这一行意味着节点已经启动:
[node] [Karkas] started
现在,可以连接到该节点并开始发送请求。
下面的gateway是负责将数据持久化到磁盘的Elasticsearch组件,这样就不会在节点宕机的时候丢失数据。
[gateway] [Karkas] recovered [0] indices into cluster_state
启动节点之后,gateway将查看磁盘来判断是否有数据在意外时保存过,这样可以恢复这些数据。目前这个例子没有索引需要恢复。
刚刚看的这些日志中,很多信息都是可以配置的,从节点名称到gateway的设置。随着全书内容的展开,我们会谈论配置的选项和相关的概念。第二部分都是关于性能和管理的内容,其中会看到配置的选项。在此之前,无需过多的配置,因为默认的值对于开发者而言非常友好。
警告
默认的取值对开发者过于友好了,以至于在同个多播网络中的另一台计算机上,启动一个新的Elasticsearch实例时,该实例会和第一个实例加入同一个集群,可能会导致无法预见的结果。例如,分片从一个节点迁移到另一个节点。为了防止这些发生,可以在elasticsearch.yml配置文件中修改集群的名称,2.5.1节会演示如何操作。
连接REST API最简单的方法是在浏览器里导航到http://localhost:9200。如果不是在本机上安装Elasticsearch,那么需要将localhost
替换为远程机器的IP地址。Elasticsearch默认监听从9200端口进入的HTTP请求。如果请求生效了,用户应该获得一个JSON应答,这也表明Elasticsearch正常工作,如图1-6所示。
图1-6 在浏览器中检阅Elasticsearch
现在一切设置完毕,让我们回顾一下本章讨论的内容:
在第2章中,读者将通过索引和搜索真实的数据,加深对Elasticsearch的了解。
e基础之上的开源分布式搜索引擎。
在第2章中,读者将通过索引和搜索真实的数据,加深对Elasticsearch的了解。