快速成长期应用架构实践 (3):开源方案实践

叁叁肆2018-11-14 18:34

欢迎访问网易云社区,了解更多网易技术产品运营经验。


4.1.3 全文检索


搜索,是用户获取信息的主要方式。在日常生活中,我们不管是购物(淘宝)、吃饭(大 众点评、美团网)还是旅游(携程、去哪儿),都离不开搜索的应用。搜索几乎成为每个网 站、APP 甚至是操作系统的标配。在用户面前,搜索通常只是展示为一个搜索框,非常干 净简洁,但它背后的原理可没那么简单,一个框的背后包含的是一整套搜索引擎的原理。 假如我们需要搭建一个搜索系统为用户提供服务,我们又需要了解什么呢? 


1. 基本原理 


首先,我们需要知道全文检索的基本原理,了解全文检索系统在实际应用中是如何工 作的。
通常,在文本中查找一个内容时,我们会采取顺序查找的方法。譬如现在手头上有一 本计算机书籍,我们需要查找出里面包含了“计算机”和“人工智能”关键字的章节。一 种方法就是从头到尾阅读这本计算机书籍,在每个章节都留心是否包含了“计算机”和“人 工智能”这两个词。这种线性扫描就是最简单的计算机文档检索方式。这个过程通常称为 grepping,它来自于 Unix 下的一个文本扫描命令 grep。在文本内进行 grepping 扫描很快, 使用现代计算机会更快,并且在扫描过程中还可以通过使用正则表达式来支持通配符查找。 总之,在使用现代计算机的条件下,对一个规模不大的文档集进行线性扫描非常简单,根 本不需要做额外的处理。但是,很多情况下只采用上述扫描方式是远远不够的,我们需要 做更多的处理。这些情况如下所述。


大规模文档集条件下的快速查找。用户的数据正在进行爆发性的增长,我们可能 需要在几十亿到上万亿规模下的数据进行查找。


有时我们需要更灵活的匹配方式。比如,在 grep 命令下不能支持诸如“计算机 NEAR 人工智能”之类的查询,这里的 NEAR 操作符的定义可能为“5 个词之内” 或者“同一句子中” 。


需要对结果进行排序。很多情况下,用户希望在多个满足自己需求的文档中得到 最佳答案。


此时,我们不能再采用上面的线性扫描方式。一种非线性扫描的方式是事先给文档建 立索引(Index)。回到上面所述的例子,假设我们让计算机对整书本预先做一遍处理,找 出书中所有的单词都出现在了哪几个章节(由于单词会重复,通常都不会呈现爆炸式增长), 并记录下来。此时再查找“计算机”和“人工智能”单词出现在哪几个章节中,只需要将 保存了它们出现过的章节做合并等处理,即可快速寻找出结果。存储单词的数据结构在信 息检索的专业术语中叫“倒排索引”(Inverted Index),因为它和正向的从章节映射到单词 关系相反,是倒着的索引映射关系。


这种先对整个文本建立索引,再根据索引在文本中进行查找的过程就是全文检索 (Full-text Search)的过程。图 4-4 展示了全文检索的一般过程。


图 4-4 全文检索的一般过程 


首先是数据收集的过程(Gather Data),数据可以来源于文件系统、数据库、Web 抓取 甚至是用户输入。数据收集完成后我们对数据按上述的原理建立索引(Index Documents), 并保存至 Index 索引库中。在图的右边,用户使用方面,我们在页面或 API 等获取到用户 的搜索请求(Get Users' Query),并根据搜索请求对索引库进行查询(Search Index), 然后 对所有的结果进行打分、排序等操作,最终形成一个正确的结果返回给用户并展示(Present Search Results)。当然在实现流程中还包含了数据抓取/爬虫、链接分析、分词、自然语言 处理、索引结构、打分排序模型、文本分类、分布式搜索系统等技术,这是最简单抽象的 流程描述。关于索引过程和搜索过程更详细的技术就不做更多介绍了,感兴趣的同学请参 考其他专业书籍。 


2. 开源框架 


根据上面的描述我们知道了全文检索的基本原理,但要是想自己从头实现一套搜索系 统还是很困难的,没有一个专业的团队、一定的时间基本上做出不来,而且系统实现之后 还需要面临生产环境等各种问题的考验,研发和维护成本都无比巨大。不过,现代的程序 开发环境早已今非昔比,开源思想深入人心,开源软件大量涌现。没有特殊的需求,没有 人会重新开发一套软件。我们可以站在开源巨人的肩膀上,直接利用开源软件的优势。目前市面上有较多的开源搜索引擎和框架,比较成熟和活跃的有以下几种。


Lucene

Solr

Elasticsearch

Sphinx


我们分别介绍这几种开源方案,并比较一下它们的优劣。


Lucene


Lucene 是一个 Java 语言开发的搜索引擎类库,也是目前最火的搜索引擎内核类库。但 需要注意的是,Lucene 本身还不是一套完整的搜索引擎解决方案,它作为一个类库只是包 含了核心的搜索、索引等功能,如果想使用 Lucene,还需要做一些额外的开发工作。


优点:

Apache 顶级项目,仍在持续快速进步。

成熟的解决方案,有很多成功案例。

庞大而活跃的开发社区,大量的开发人员。

虽然它只是一个类库,但经过简单的定制和开发,就可以满足绝大部分常见的需 求;经过优化,可以支持企业级别量级的搜索。


缺点:

需要额外的开发工作。系统的扩展、分布式、高可用性等特性都需要自己实现。


Solr

Solr 是基于 Lucene 开发、并由开发 Lucene 的同一帮人维护的一套全文搜索系统,Solr 的版本通常和 Lucene 一同发布。Solr 是最流行的企业级搜索引擎之一。


优点: 

由于和 Lucene 共同维护,Solr 也有一个成熟、活跃的社区。 

Solr 支持高级搜索特性,比如短语搜索、通配符搜索、join、group 等。

Solr 支持高吞吐流量、高度可扩展和故障恢复。

支持 REST 风格 API,支持 JSON、XML、CSV 甚至二进制格式的数据;功能强 大的综合管理页面、易于监控。

Solr 已比较成熟、稳定。


缺点:

系统部署、配置及管理配置上的使用较为复杂。


Elasticsearh 

Elasticsearch 是一个实时的分布式搜索和分析引擎,和 Solr 一样,它底层基于 Lucene 框架。但它具有简单、易用、功能/性能强大等优点,虽然晚于 Solr 出现,但迅速成长,已 成为目前当仁不让的最热门搜索引擎系统。


优点:

支持 REST 风格的 HTTP API,并且事件完全受 API 驱动,几乎所有的操作都可以 通过使用 JSON 格式的 RESTful HTTP API 完成。

支持多租户/多索引(multi-tenancy),支持全面的高级搜索特性。

索引模式自由(Schema Free),支持 JSON 格式数据;部署、配置简单,便于使用。

强大的聚合(Aggregation)分析功能(取代 Lucene 传统的 Facets),便于用户对 数据进行统计分析。


缺点:

几乎无缺点,在性能和资源上较 C++ 开发的 Sphinx 稍差。


Sphinx 

Sphinx 是基于 C++ 开发的一个全文检索引擎,从最开始设计时就注重性能、搜索相关 性及整合简单性等方面。Sphinx 可以批量索引和搜索 SQL 数据库、NoSQL 存储中的数据, 并提供和 SQL 兼容的搜索查询接口。


优点:

Sphinx 采用 C++ 开发,因此支持高速的构建索引及高性能的搜索。 

支持 SQL/NoSQL 搜索。

方便的应用集成。

更高级的相似度计算排序模型。


缺点:

社区、生态等不如 Lucene 系发达,可见的成功案例较少。

应用选型 

通过上面的介绍,相信大家对各个开源搜索系统所适用的场景有了一定了解。


如果是中小型企业,想快速上手使用搜索功能,可以选择 Elasticsearch 或 Solr。如果 对搜索性能和节省资源要求比较苛刻,可以考虑尝试 Sphinx。如果有很多定制化的搜索功 能需求,可以考虑在 Lucene 基础上做自定义开发。如果用于日志搜索,或者有很多的统计、 分析等需求,可以选择 Elasticsearch。


3. 开源方案实践 


如上述介绍,在实际开发当中已有了很多现成的开源方案可供选择,但我们还是需要 额外再做一些事情。譬如集群搭建、维护和管理、高可用设计、故障恢复、最基本的机房 申请及机器采购部署等。这也需要投入较高的人力和成本(虽然较自己研发已经节省很多), 并且还需要配备专业的搜索开发及运维人员。


而在网易云中,我们基于开源 Elasticsearch 系统提供了一套简单的方案。我们把专业、 复杂的搜索系统服务化和简单化,并降低准入门槛和成本,让用户可以直接使用平台化的 搜索服务。我们提供了全面的近实时、高可用、高可靠、高扩展等搜索系统强大功能,易 于用户使用。用户使用网易云的云搜索后不再需要处理搜索系统的搭建与配置工作,而只 需要在云搜索服务的产品管理平台申请建立服务实例并配置索引数据格式,申请完成后云 搜索平台就会自动生成索引服务实例并提供全文检索服务。 


文章节选自《云原生应用架构实践》 网易云基础服务架构团队 著


网易云计算基础服务深度整合了 IaaSPaaS 及容器技术,提供弹性计算、DevOps 工具链及微服务基础设施等服务,帮助企业解决 IT、架构及运维等问题,使企业更聚焦于业务,是新一代的云计算平台。点击可免费试用