搜索引擎之Lucene,Solr,ElasticSearch比较
1 搜索引擎
1.1 简介
全文搜索引擎
是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
1.2 结构化数据和非结构化数据
数据总体分为两种:
结构化数据
:指具有固定格式或有限长度的数据,如数据库,元数据等。非结构化数据
:非结构化数据又可称为全文数据,指不定长或无固定格式的数据,如邮件,Word 文档等。
当然有的地方还会有第三种:半结构化数据,如 XML,HTML 等,当根据需要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。
根据两种数据分类,搜索也相应的分为两种:结构化数据搜索和非结构化数据搜索。
对于结构化数据,我们一般都是可以通过关系型数据库(MySQL,Oracle 等)的 table 的方式存储和搜索,也可以建立索引。
对于非结构化数据,也即对全文数据的搜索主要有两种方法:
顺序扫描
:通过文字名称也可了解到它的大概搜索方式,即按照顺序扫描的方式查询特定的关键字。
例如一张报纸,让你找到该报纸中“RNG”的文字在哪些地方出现过。你肯定需要从头到尾把报纸阅读扫描一遍,然后标记出关键字在哪些版块出现过以及它的出现位置。
这种方式无疑是最耗时的最低效的,如果报纸排版字体小,而且版块较多甚至有多份报纸,等你扫描完眼睛也差不多了。全文检索
:对非结构化数据顺序扫描很慢,我们是否可以进行优化?把我们的非结构化数据想办法弄得有一定结构不就行了吗?
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
这种方式就构成了全文检索的基本思路。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
还以读报纸为例,我们想关注英雄联盟 S8 全球总决赛的新闻,假如都是 RNG 的粉丝,如何快速找到 RNG 新闻的报纸和版块呢?
全文检索的方式就是,将所有报纸中所有版块中关键字进行提取,如"EDG","RNG","FW","战队","英雄联盟"等。
然后对这些关键字建立索引,通过索引我们就可以对应到该关键词出现的报纸和版块。注意区别目录搜索引擎
1.3 倒排索引
如何理解倒排索引呢? 假如现有三份数据文档,文档的内容如下分别是:
Java is the best programming language.
PHP is the best programming language.
Javascript is the best programming language.
为了创建倒排索引,我们通过分词器将每个文档的内容域拆分成单独的词(我们称它为词条或 Term
),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。
结果如下所示
Term | Doc_1 | Doc_2 | Doc_3 |
---|---|---|---|
Java | X | ||
is | X | X | X |
the | X | X | X |
best | X | X | X |
programming | x | X | X |
language | X | X | X |
PHP | X | ||
Javascript | X |
这种结构由文档中所有不重复词
的列表构成,对于其中每个词都有一个文档列表与之关联。
这种 由属性值来确定记录的位置的结构就是倒排索引
。带有倒排索引的文件我们称为倒排文件
我们将上面的内容转换为图的形式来说明倒排索引的结构信息,如下图所示:
其中主要有如下几个核心术语需要理解:
- 词条(
Term
): 索引里面最小的存储和查询单元,对于英文来说是一个单词,对于中文来说一般指分词后的一个词。 - 词典(
Term Dictionary
): 或字典,是词条Term
的集合。搜索引擎的通常索引单位是单词
,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向倒排列表
的指针。 - 倒排表(
Post list
):一个文档通常由多个词组成,倒排表记录的是某个词在哪些文档里出现过以及出现的位置。每条记录称为一个倒排项(Posting
)。倒排表记录的不仅是文档编号,还存储了词频等信息。 - 倒排文件(
Inverted File
): 所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件被称之为倒排文件
,倒排文件是存储倒排索引的物理文件
词典
和倒排表
是 Lucene
中很重要的两种数据结构,是实现快速检索的重要基石。词典
和倒排文件
是分两部分存储的,词典在内存中
而倒排文件存储在磁盘
上
1.4 使用全文搜索引擎条件
什么时候使用全文搜索引擎:
- 搜索的数据对象是大量的非结构化的文本数据。
- 文件记录量达到数十万或数百万个甚至更多。
- 支持大量基于交互式文本的查询。
- 需要非常灵活的全文搜索查询。
- 对高度相关的搜索结果有特殊需求,但是没有可用的关系数据库可以满足。
- 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况
2 Lucene,Solr,ElasticSearch
现在主流的搜索引擎大概就是:Lucene,Solr,ElasticSearch
。
它们的索引建立都是根据倒排索引的方式生成索引
倒排索引
(英语:Inverted index
),也常被称为反向索引
、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构
2.1 Lucene
Lucene
是一个 Java
全文搜索引擎,完全用 Java
编写。Lucene
不是一个完整的应用程序,而是一个代码库和 API
,可以很容易地用于向应用程序添加搜索功能。Lucene
通过简单的 API
提供强大的功能:
可扩展的高性能索引:
- 在现代硬件上超过 150GB /小时。
- 小 RAM 要求,只有 1MB 堆。
- 增量索引与批量索引一样快。
- 索引大小约为索引文本大小的 20-30%。
强大,准确,高效的搜索算法:
- 排名搜索:首先返回最佳结果。
- 许多强大的查询类型:短语查询,通配符查询,邻近查询,范围查询等。
- 现场搜索(例如标题,作者,内容)。
- 按任何字段排序。
- 使用合并结果进行多索引搜索。
- 允许同时更新和搜索。
- 灵活的分面,突出显示,连接和结果分组。
- 快速,内存效率和错误容忍的建议。
- 可插拔排名模型,包括矢量空间模型和 Okapi BM25。
- 可配置存储引擎(编解码器)
跨平台解决方案:
- 作为
Apache
许可下的开源软件提供 ,允许在商业和开源程序中使用Lucene
- 100%-pure Java。
- 可用的其他编程语言中的实现是索引兼容的。
Apache
软件基金会:
- 获得
Apache
软件基金会提供的开源软件项目的 Apache 社区的支持。 Lucene
只是一个框架,要充分利用它的功能,需要使用 Java,并且在程序中集成Lucene
。需要很多的学习了解,才能明白它是如何运行的,熟练运用 Lucene 确实非常复杂
2.2 Solr
Apache Solr
是一个基于名为 Lucene
的 Java
库构建的开源搜索平台。它以用户友好的方式提供 Apache Lucene
的搜索功能。它是一个成熟的产品,拥有强大而广泛的用户社区。
它提供分布式索引,复制,负载平衡查询以及自动故障转移和恢复。如果它被正确部署然后管理得好,它就能够成为一个高度可靠,可扩展且容错的搜索引擎。
很多互联网巨头,如 Netflix,eBay,Instagram 和亚马逊(CloudSearch)都使用 Solr
,因为它能够索引和搜索多个站点。
主要功能列表包括:
- 全文搜索
- 突出
- 分面搜索
- 实时索引
- 动态群集
- 数据库集成
NoSQL
功能和丰富的文档处理(例如 Word 和 PDF 文件)
2.3 ElasticSearch
Elasticsearch
是一个开源(Apache 2 许可证),基于 Apache Lucene
库构建的 RESTful
搜索引擎。
Elasticsearch
是在 Solr
之后几年推出的。它提供了一个分布式,多租户能力的全文搜索引擎,具有 HTTP Web
界面(REST
)和无架构 JSON
文档。
Elasticsearch
的官方客户端库提供 Java,Groovy,PHP,Ruby,Perl,Python,.NET 和 Javascript
。
分布式搜索引擎包括可以划分为分片的索引,并且每个分片可以具有多个副本。
每个Elasticsearch
节点都可以有一个或多个分片,其引擎也可以充当协调器,将操作委派给正确的分片。
Elasticsearch
可通过近实时搜索进行扩展。其主要功能之一是多租户。主要功能列表包括:
- 分布式搜索
- 多租户
- 分析搜索
- 分组和聚合
2.4 区别和选择
2.4.1 如何选择
由于 Lucene
的复杂性,一般很少会考虑它作为搜索的第一选择,排除一些公司需要自研搜索框架,底层需要依赖 Lucene
。
Apache Solr
是一个成熟的项目,拥有庞大而活跃的开发和用户社区,以及 Apache
品牌。
Solr
于 2006 年首次发布到开源,长期以来一直占据着搜索引擎领域,并且是任何需要搜索功能的人的首选引擎。
它的成熟转化为丰富的功能,而不仅仅是简单的文本索引和搜索;如分面,分组,强大的过滤,可插入的文档处理,可插入的搜索链组件,语言检测等。
Solr
在搜索领域占据了多年的主导地位。然后,在 2010 年左右,Elasticsearch
成为市场上的另一种选择。那时候,它远没有 Solr
那么稳定,没有 Solr
的功能深度,没有思想分享,品牌等等。
Elasticsearch
虽然很年轻,但它也自己的一些优势,Elasticsearch
建立在更现代的原则上,针对更现代的用例,并且是为了更容易处理大型索引和高查询率而构建的。
此外,由于它太年轻,没有社区可以合作,它可以自由地向前推进,而不需要与其他人(用户或开发人员)达成任何共识或合作,向后兼容,或任何其他更成熟的软件通常必须处理。
因此,它在 Solr
之前就公开了一些非常受欢迎的功能(例如,接近实时搜索,英文:Near Real-Time Search
)。
从技术上讲,NRT
搜索的能力确实来自 Lucene
,它是 Solr
和 Elasticsearch
使用的基础搜索库。
尽管 Solr
和 Lucene
都是同一个 Apache
项目的一部分,但是,人们会首先期望 Solr
具有如此高要求的功能。
2.4.2 区别
这两个搜索引擎都是流行的,先进的的开源搜索引擎。它们都是围绕核心底层搜索库 Lucene
构建的,但它们又是不同的。
像所有东西一样,每个都有其优点和缺点,根据需求和期望,每个都可能更好或更差。
Solr
和 Elasticsearch
都在快速发展,所以,话不多说,先来看下它们的差异清单:
2.4.2.1 流行趋势
我们查看一下这两种产品的 Google 搜索趋势。谷歌趋势表明,与 Solr 相比,Elasticsearch 具有很大的吸引力,但这并不意味着 Apache Solr 已经死亡。
虽然有些人可能不这么认为,但 Solr 仍然是最受欢迎的搜索引擎之一,拥有强大的社区和开源支持。
2.4.2.2 安装和配置
与 Solr
相比,Elasticsearch
易于安装且非常轻巧。此外,可以在几分钟内安装并运行 Elasticsearch
。
但是,如果 Elasticsearch
管理不当,这种易于部署和使用可能会成为一个问题。
基于 JSON
的配置很简单,但如果要为文件中的每个配置指定注释,那么它不适合。
总的来说,如果的应用使用的是 JSON,那么 Elasticsearch 是一个更好的选择。
否则,请使用 Solr,因为它的 schema.xml 和 solrconfig.xml 都有很好的文档记录。
2.4.2.3 社区
Solr
拥有更大,更成熟的用户,开发者和贡献者社区。ES 虽拥有的规模较小但活跃的用户社区以及不断增长的贡献者社区。
Solr 是真正的开源社区代表。任何人都可以为 Solr 做出贡献,并且根据优点选出新的 Solr 开发人员(也称为提交者)。
Elasticsearch
在技术上是开源的,但在精神上却不那么重要。任何人都可以看到来源,任何人都可以更改它并提供贡献,但只有 Elasticsearch
的员工才能真正对 Elasticsearch
进行更改。
Solr
贡献者和提交者来自许多不同的组织,而 Elasticsearch
提交者来自单个公司。
2.4.4.4 成熟度
Solr
更成熟,但 ES
增长迅速,稳定
2.4.4.5 文档
Solr
在这里得分很高。它是一个非常有据可查的产品,具有清晰的示例和 API
用例场景。
Elasticsearch
的文档组织良好,但它缺乏好的示例和清晰的配置说明。
2.4.3 总结
那么,到底是选择 Solr
还是 Elasticsearch
?有时很难找到明确的答案。无论选择 Solr
还是 Elasticsearch
,首先需要了解正确的用例和未来需求,总结它们的每个属性。
记住下面这些要点:
- 由于易于使用,
Elasticsearch
在新开发者中更受欢迎。但是,如果已经习惯了与Solr
合作,请继续使用它,因为迁移到Elasticsearch
没有特定的优势。 - 如果除了搜索文本之外还需要它来处理分析查询,Elasticsearch 是更好的选择。
- 如果需要分布式索引,则需要选择
Elasticsearch
。对于需要良好可伸缩性和性能的云和分布式环境,Elasticsearch
是更好的选择。 - 两者都有良好的商业支持(咨询,生产支持,整合等)。
- 两者都有很好的操作工具,尽管
Elasticsearch
因其易于使用的 API 而更多地吸引了 DevOps 人群,因此可以围绕它创建一个更加生动的工具生态系统。 Elasticsearch
在开源日志管理用例中占据主导地位,许多组织在Elasticsearch
中索引它们的日志以使其可搜索。虽然Solr
现在也可以用于此目的,但它只是错过了这一想法。Solr
仍然更加面向文本搜索。另一方面,Elasticsearch
通常用于过滤和分组,分析查询工作负载,而不一定是文本搜索。Elasticsearch
开发人员在Lucene
和Elasticsearch
级别上投入了大量精力使此类查询更高效(降低内存占用和 CPU 使用)。因此,对于不仅需要进行文本搜索,而且需要复杂的搜索时间聚合的应用程序,Elasticsearch
是一个更好的选择。Elasticsearch
更容易上手,一个下载和一个命令就可以启动一切。Solr
传统上需要更多的工作和知识,但Solr
最近在消除这一点上取得了巨大的进步- 在性能方面,它们大致相同。说“大致”,因为没有人做过全面和无偏见的基准测试。对于
95%
的用例,任何一种选择在性能方面都会很好,剩下的 5% 需要用它们的特定数据和特定的访问模式来测试这两种解决方案。 - 从操作上讲,
Elasticsearch
使用起来比较简单,它只有一个进程。Solr
在其类似Elasticsearch
的完全分布式部署模式SolrCloud
中依赖于Apache ZooKeeper
,ZooKeeper
是超级成熟,超级广泛使用等等,但它仍然是另一个活跃的部分。也就是说,如果使用的是 Hadoop,HBase,Spark,Kafka 或其他一些较新的分布式软件,可能已经在组织的某个地方运行 ZooKeeper。 - 虽然
Elasticsearch
内置了类似ZooKeeper
的组件Xen
,但ZooKeeper
可以更好地防止有时在Elasticsearch
集群中出现的可怕的裂脑问题。公平地说,Elasticsearch
开发人员已经意识到这个问题,并致力于改进Elasticsearch
的这个方面。 - 如果喜欢监控和指标,那么使用
Elasticsearch
,将会进入天堂。Solr
暴露了关键指标,但远不及Elasticsearch
那么多。
总之,两者都是功能丰富的搜索引擎,只要设计和实现得当,它们或多或少都能提供相同的性