Elasticsearch是一个开源的分布式实时搜索与分析引擎,支持云服务。它是基于Apache Lucene搜索引擎的类库创建的,提供了全文搜索能力、多语言支持、专门的查询语言、支持地理位置服务、基于上下文的搜索建议、自动完成以及搜索片段(snippet)的能力。
Elasticsearch支持RESTful的API,可以使用JSON通过HTTP调用它的各种功能,包括搜索、分析与监控。此外,它还为Java、PHP、Perl、Python以及Ruby等各种语言提供了原生的客户端类库。Elasticsearch可以在Apache 2许可下进行使用。作为Elasticsearch-hadoop的第一个里程碑,它的1.3.M1版本在十月上旬发布了。
InfoQ与Elasticsearch团队的Costin Leau进行了一次对话,谈论了Elasticsearch的搜索与分析引擎,以及它是如何与Hadoop或其它的大数据技术相结合的。
InfoQ:你好Costin,你能为我们描述一下Elasticsearch是什么,以及它是如何实现大数据方面的需求的吗?
Elasticsearch是一个高伸缩、高可用、基于Apache Lucene的开源搜索与分析引擎。通过它你可以很方便地对数据进行深入挖掘,可以随时放大与缩小搜索与分析的区间,并且这一切都是实时的。为了提供了一个优秀的用户体验,我们对Elasticsearch投入了很大的精力。Elasticsearch本身的各种选项已有了良好的默认值,使用户能够更方便地上手。但我们也为用户提供了全方面的选项,在必要的情况下,可以对该引擎的几乎每个方面进行定制。
举例来说,当你使用它搜索数据的时候,可以使用传统的查询(‘查找满足条件Y的所有项X’)进行过滤(在Elasticsearch术语中称为“视图”),高亮显示搜索片段,为每条结果提供相应的上下文。也可以使用地理位置(‘查找在Z里之内的所有项’),或是为用户提供搜索关键字建议,并且提供了强大的聚合(即Elasticsearch中的“分面”(facet))能力,例如时间分布图或者统计图。
Elasticsearch既可以搜索、也可以保存数据。它提供了一种半结构化、不依赖schema并且基于JSON的模型,你可以直接传入原始的JSON文档,Elasticsearch会自动地检测出你的数据类型,并对文档进行索引。你也可以对schema映射进行定制,以实现你的目的,例如对单独的字段或文档进行boost映射,或者是定制全文搜索的分析方式等等。
你既可以在自己的膝上电脑中启用一个小型实例,也可以在云端启用几十乃至几百个实例,只需要一些极小的改变而已。Elasticsearch会自动进行横向扩展,它能够随着你的应用一起成长。
Elasticsearch运行在JVM之上,它使用JSON格式,通过RESTful HTTP接口的方式访问,因此任何一种客户端或语言都能够与其交互。目前已经有了大量的客户端和框架的整合方案,包括对多种编程语言的支持,通过这些原生的API与专门的DSL将不一致的地方最小化,并实现性能最大化。
Elasticsearch非常适合于大数据的场合,它的高伸缩性与分布式架构的本质使得对大量信息的搜索与存储都可以在近乎实时的情况下完成。通过Elasticsearch-Hadoop这个项目,我们使Hadoop使用者(这里也包括Hive、Pig和Cascading)能够用一个成熟的搜索引擎来增强他们的工作流。我们还为他们提供了一种丰富的语言,能够让他们更好地表达意图,因而更准确地获得想要的结果,并且速度也大大提高了。
InfoQ:Elasticsearch是用于实时全文搜索的。你能否告诉我们实时的全文搜索与传统的数据搜索有什么不同吗?
按照通俗的说法,传统的搜索其实就是全文搜索的一个子集。
大多数数据存储系统都是基于元数据,或是原始数据的某些部分实现搜索功能的。出于效率方面的原因,那些我们认为相关的数据子集(例如对象的id、name等等)会被索引,而其余部分则被忽略。与原始数据大小相比,所生成的索引数据量比较小,但它没有完全覆盖到所有的数据集。全文搜索解决这个问题的方式是对整个数据资料进行索引和搜索,代价就是对存储空间的需求增加。
传统的搜索通常是与结构化数据相关的,因为对用户来说结构化数据更容易理解哪些数据是相关的,而哪些是不相关的。但当前的业务中,大多数数据都是非结构化的。你会将所有数据一次性保存起来,在需要的时候再去获取它的各种不同格式与结构的值,在这种情况下就必需用到全文搜索的方式,因为你已经无法忽略任何数据了。
Elasticsearch同时支持结构化数据搜索与全文搜索,它提供了大量的查询选项,包括关键字、布尔查询、过滤器以及模糊查询等方式,所有这些都选项都可以通过一个丰富的查询语言来完成。
请注意,Elasticsearch与简单的全文搜索相比,还提供了以下一些额外的特性:
- 地理位置查询:根据数据的地理位置查找结果。
- 聚合/分面:在查询的时候进行数据聚合,例如查找在某一天之内,访问过你的网站中某篇特定文章,或者是某些标签的用户来自哪些国家。由于聚合是实时计算的,因此当查询变化时,聚合也会相应的变化。换句话说,就是你总能获取数据集的即时反馈。
InfoQ:在使用Elasticsearch时,有哪些设计上的考虑呢?
数据是王道,因此要专注于对它的处理。为了让Elasticsearch能够按照你设想的方式处理数据,它必须理解你的“需求”。虽然它能够尽最大努力去猜测你要的数据,但你的领域知识对于进行正确的配置以支持你的需求来说才是最有价值的部分。这些都可以归结为数据的粒度或者是组织方式。让我们拿日志这个常见的需求来举个例子:与其把所有的日志记录都放在一个巨大的索引里,更好的方法是将日志记录按照时间进行分解,因此每月、每周或者每天的数据都可以对应一条索引。这种分解方式能够在你处理数据巨量增长、以及删除或者归档旧数据时带来许多便利。
InfoQ:能否请你谈谈Elasticsearch引擎所支持的设计与架构模式呢?
一个索引包括了多个分片,每个分片本身就是一个迷你的搜索引擎。一个索引本质上就是对应着一系列分片的虚拟命名空间。多分片的方式能够简化横向扩展任务,只需添加新的节点即可。而创建分发分片对每个主分片的数据进行复制能够实现高可用性,并增加读取时的吞吐能力。
查询某个索引是一种分布式操作,这意味着Elasticsearch不得不对索引中的每个分片的数据复制进行查询,并将结果整理到一个单一的结果集中。而对多个索引进行查询只是将相同的步骤进一步扩大了而已。在设计你的数据存储架构时,这种方式能够带来极大的灵活性。
而如果用户了解他的应用程序特定的一些领域知识,那就可以对查询进行优化,使查询只触及相关的分片。在同样的硬件条件下,这种方式可以支持更大的负载。
InfoQ:Elasticsearch是怎样支持数据的可伸缩性的呢?
为了支持高可用性与高伸缩性,Elasticsearch本身就是分布式设计的。从顶层的角度来说,Elasticsearch在索引(或者集合)中保存文档(或者数据记录),每个集合又分解为多个小块,称为分片。索引越大,所需要分配的分片越多(不必担心会创建过多的分片,它的开销很小)。取决于Elasticsearch的设置和规模,分片会在集群中均匀地平均分布,有两个原因:
出于冗余方面的原因:默认情况下,Elasticsearch为每个分片都准备了一份拷贝,一旦某个节点停机了,备份的分片就能接替它的位置。
出于性能方面的原因:每个查询都发生在某个索引上,并且会在多个分片中并行运行,这种工作流方式是改善性能的关系所在。如果感觉运行速度缓慢,只需简单地在集群中加入新的机器,Elasticsearch就会自动地将分片与查询进行分布到新添加的机器上。
这种方式让使用Elasticsearch的组织可以自由选择进行纵向扩展(如果节点运行缓慢就升级硬件)或者横向扩展(如果集群整体速度慢就加入更多的节点)。
InfoQ:在使用这种解决方案时有什么限制,或者是要特别留意的地方吗?
我认为最大的挑战是用户从SQL的世界来到了这个基于上下文的搜索世界时所面对的新理念,对于获取独立的数据项(传统的数据获取)来说,方法基本还是一样的,只要指定id然后取回数据就可以了。但对于数据探索来说,所使用的各种构造就有所不同了,例如采用不同类型的分析方式,或是使用哪种类型的搜索或匹配算法(如模糊查询等等)。
InfoQ:你能否说说联合使用Elasticsearch与Hadoop技术具有什么优势吗?
Hadoop在设计上就是一个分布式的,面向批处理的平台,用以处理大数据集。虽然它是一个非常强大的工具,但它的批处理的本质意味着在处理结果时需要花费一定时间。此外,用户必需重新为各种操作编写代码。Hive或者Pig这样的类库能起到一定作用,但不能完全解决问题,想象一下在Map/Reduce中重新实现地理位置查询的难度吧。
而使用Elasticsearch,你就可以将搜索工作交给搜索引擎去完成,而专注于其它方面的工作,例如数据转换。Elasticsearch-Hadoop项目为Hadoop提供了直接的整合功能,因此用户使用起来没有任何障碍,我们为vanilla Map/Reduce提供了专门的InputFormat与OutputFormat,为Cascading的数据读写提供了Taps,并为Pig和Hive提供了Storages。这样你就可以以HDFS一样方式的访问Elasticsearch的数据了。
通常来说,与Hadoop进行整合的数据存储系统都可能会成为系统的瓶颈,这是由于每个job在集群中的各种任务会造成大量的请求。而Map/Reduce模型的分布式特性用于Elasticsearch上会配合得非常良好,因为我们能够将某个特定查询所生产的Map/Reduce任务数量与Elasticsearch的分片数量相关联。这样每次有查询运行时,系统就会动态地按照Hadoop的划分生成一个数值,该数值与Elasticsearch的可用分片数量成正比,这样各个job就能够并行地运行了。你可以按照Elasticsearch的数量对Hadoop集群进行扩展,或者是反过来也可以。
此外,这种整合将分片的信息暴露给Hadoop,以此可以实现协同定位。Job的任务会在每个Elasticsearch分片所在的同一台机器上运行,通过实现数据本地化消除了网络的开销,并改善了性能。出于这个原因,我们建议你在相同的机器上运行Elasticsearch和Hadoop集群,尤其是他们能够互相平衡资源的使用情况(I/O与CPU)。
最后但也是很重要的一点是,Elasticsearch能够提供近乎实时的响应速度(毫秒等级),这极大的改善了Hadoop job的执行速度以及执行的各种开销,在类似于Amazon EMR这种“租用的资源”上运行时的改善尤其明显。
InfoQ:Spring框架与Elasticsearch是否能够进行整合呢?
当然能了,请去查看一下Github上的Spring Data Elasticsearch项目。该项目是由我们的社区成员组织Biomed Central启动的,而我们也乐于和他们共同参与开发的过程,使用并改善这一项目。该项目提供了一个大家所熟悉的Spring模板,作为一个高级别的抽象层。Repository的实现是基于Elasticsearch的功能,另外还通过XML、JavaConfig和CDI提供了各种配置能力。我们目前正致力于将各种整合项目聚合在一起,其中最受关注的就是David Piloto开发的spring-elasticsearch项目了。
Costin Leau是ElasticSearch的一位工程师,目前在从事NoSQL与大数据技术的研究。作为一名开源方面的老手,Costin带领了多个Spring项目的开发,并编写了一份OSGi规格说明书。
查看英文原文:Costin Leau on Elasticsearch, BigData and Hadoop