10
回答
【开源访谈】蚁坊软件平台部何小成:一个超大规模搜索引擎背后的故事
华为云实践训练营,热门技术免费实践!>>>   

湖南蚁坊软件股份有限公司是一家高新技术企业,专业从事互联网大数据分析,专注于大数据信息的挖掘和价值传递。蚁坊软件拥有自主品牌的大数据服务云——蚁工厂(Antfact),日处理10亿多条实时数据。如何保证平台的性能呢?目前的搜索引擎存在着怎样的技术瓶颈?如何选择 Apache Solr 和 Elasticsearch?带着这些问题,本期开源访谈邀请到了蚁坊软件蚁工厂团队何小成,和大家一起了解一个超大规模搜索引擎背后的故事。

【本期嘉宾】

何小成,就职于湖南蚁坊软件股份有限公司蚁工厂团队。主要从事超大规模分布式搜索引擎的平台设计、开发和优化等工作。实现在高并发、日处理10亿多条实时数据的情况下,对 PB 级的数据做快速搜索和统计。深度剖析过 Apache Solr、Elasticsearch、Lucene 等开源索引框架结构以及其性能调优的工作。

【访谈实录】

1. 嘉宾自我介绍

我是何小成,现在在蚁坊软件做蚁工厂大数据服务云的开发。我的工作主要是负责大数据服务云的平台建设和性能优化。现在主要是负责优化搜索引擎这方面的工作。因为我们平时的业务涉及到很大的数据量,每天有10亿多条实时数据需要建立索引,同时建索引同时提供搜索服务,对并发性能要求很高。因此,对性能的需求理所当然就摆在了首位。

工作中,我们使用了两个开源的搜索引擎项目。分别是 Apache Solr 和 Elasticsearch。这两个项目都是基于 Lucene 实现的。我们对底层的 Lucene 进行了深度的剖析,包括它的数据结构、算法以及它的原理等。然后在其基础上,做一些性能的优化和改进。

2. 当初为什么选择搜索引擎优化这个领域?

因为刚开始就对大数据这个领域十分感兴趣,所以就选择了进入大数据这个领域。在大数据领域,对于数据的处理可分为两种,分别是 OLAP 和 OLTP。我对于 OLTP 比较感兴趣,因为它是实时数据处理而不是离线的分析。而 OLTP 需要搜索引擎做支撑,所以选择了进入搜索引擎这个领域。

3. 老师认为搜索引擎目前的技术发展瓶颈是什么?

目前看来,主要有以下的一些发展瓶颈:

1. 关于中文的搜索。因为汉语的博大精深,会存在很多的语义上的歧义,因此很难实现让机器像人一样理解一句话的含义,然后搜索相关符合的数据并返回。现在面临的挑战就是如何精准地将信息反馈给用户,这里主要的瓶颈就是对语义的理解,目前机器还不能做到百分百完全理解用户的意图。

2. 还有就是语音搜索和图片搜索。比如说搜索“我想吃西餐”,那么得到的结果应该是附近西餐厅的推荐信息,而不仅仅是罗列一些网页的链接。不过我相信以后搜索引擎会越来越智能,用户越来越依赖于搜索引擎。

4. 这样看来,对开发者会有哪些挑战?

对于开发者,主要有下面的挑战:

1. 大数据领域面临的最大挑战就是性能。因为大数据的特点就是数据量非常大,而且可能会出现某天数据量像洪水般上涨的情况,因此对开发者来说,提升搜索引擎的性能是他们的挑战之一。

2. 还有就是中文分词。因为在中文里面某个句子的断句方式不同会产生完全不一样的含义,所以中文分词也是一个很难解决的问题,具有很大的挑战性。

5. 目前你们采用怎样的解决方案,或者说是怎样解决这些问题的?

因为目前有人工智能这方面的技术,因此我们可以通过机器学习,通过分析海量的数据,更加准确地得到用户想要的结果。

比如刚刚提到有关歧义的问题,如何分词才能更贴近用户所表达的含义呢?目前主要是通过分析海量数据,基于统计概率得到词与词之间的关系,选择一种最符合语境的分词方式。

6. 让搜索引擎更智能、更符合使用者需求需要经历什么?

从搜索引擎运行的几个阶段来看一下:

要让搜索引擎更智能,首先需要对数据进行精细化处理。第一阶段,在构建索引的时候,需要做一系列的数据分析。例如,我们公司的舆情监测系统会对获取到的互联网公开数据做一系列的实时流处理,在这过程中,会做一些数据汇聚、过滤、聚类的工作,让原始数据有多元化的特征。

第二阶段是在用户层发生的。它会在用户输入搜索内容(提供多元化的特征搜索语法)的时候进行一系列的计算,得到用户所表达的最准确的意思。

第三阶段是搜索引擎根据条件返回用户需要的结果。搜索结果的排序会按照相关性进行排序,更贴近用户需要的结果排在前面。

7. 您觉得下一代搜索引擎技术会在那些方面有所突破?

随着搜索引擎不断地发展,需要用到它的地方和使用的用户也越来越多了。这就产生了一种多元化,可能会有这样一种需求 — 去兼容每一种类型的用户群体,因此它面临的发展更多的可能是在人工智能这方面,更贴近用户的需求、强化用户信息反馈这一系列会有重大的突破。

8. 像刚刚提到的 Solr、Elasticsearch,您觉得选择它们的时候要从哪方面进行考虑?

先从 Lucene 开始说吧。Lucene 比较适合用于轻量级的搜索,如果是不需要太复杂的搜索功能的场景,可以自己用 Lucene 完成自己的搜索需求。

但如果在大数据领域,采用上面的方式自己编写搜索引擎就需要付出很大的精力和时间,一般不建议这种做法。

如果是用于分布式系统的搜索引擎,一般会选择 Apache Solr 或 Elasticsearch。那么对于这两者又该如何选择呢?

Elasticsearch 发布的时间比 Apache Solr 晚,它是面向大数据的,甚至可以说为大数据而生。而 Apache Solr 面世的时间已经比较久了,刚发布的时候也没特定面向哪个领域。目前很多电商平台例如淘宝、京东都是采用 Apache Solr。这两者各有各的优势,Apache Solr 适合用于非实时写入的场景,Elasticsearch 则适合用于实时写入量比较大的场景。

还需要注意的是,Apache Solr 支持自定义的扩展,可以通过使用插件的方式进行扩展。 Elasticsearch 也提供插件扩展功能,但对于底层的一些内核组件则不方便扩展。

9. 目前主要是做哪方面的扩展?

第一个是改造了 Apache Solr 里面的索引组件。Apache Solr 内置的索引有几种,一种是 RAM Directory ,一种是 File System Directory 文件系统方面的,还有一种是 HDFS Directory ,主要是这三种类型。

现在主要是对索引组件进行了扩展。如果索引数据存放在磁盘,会存在 IO 的性能瓶颈,我们的业务实时写入量很大,并发量也很高,Apache Solr 不能满足我们的这种读写要求。因此我们采用了使用内存存放数据,但 RAM Directory 的内存是在堆内的,在数据量比较大的情况下,GC 的时间会很长,导致性能下降。

因此,我们选择使用堆外内存,即 Native Memory。我们用物理内存,自己实现了一个内存池,达到的效果跟使用 RAM Directory 的效果一样,但是不受 GC 的影响,性能有了显著提高。

还有一个问题,如果完全使用内存存放索引数据,会存在一个风险 — 数据容易丢失。所以我们会同时使用  File System Directory 做数据备份,以防数据丢失。

10. 从学习者的角度来看,如果要进入这个搜索引擎这个领域,要具备那些技术栈?

在这个领域,如果从事的工作和性能优化有关,那么必不可少的就是要对 Java 的虚拟机要非常熟悉,Java 功底要扎实,更重要的是要有很强的源代码阅读能力。优化搜索引擎必须要深入了解系统的框架结构,阅读源码则是必经之路。另外对于多线程处理、分布式计算、自然语言处理以及机器学习等技术也要有深入了解。

关于阅读源代码,其实这是一个循序渐进的过程,贵在坚持,一天不能理解就坚持每天都阅读,坚持下去一定会有收获的。

还有一点,如果前人已经做好了很多工作,当然可以先学习别人的,然后自己再深入的研究。这样可以少走很多弯路。

11. 对于开源有什么样的看法,是否有参与开源项目的计划?

对于开源的体会就是,如果自己闭门造车的话,肯定会有很多曲折,甚至会沿着错误的方向前进而不自知。但如果借助于开源,每个人都会发挥各自的优势去维护项目,项目一定会逐渐成长,不断地完善,自己也会有很大的提高。

现在已经积极参与 Apache Lucene 的社区,把工作中遇到的一些问题和想法提交到社区,为社区贡献一点微薄之力。

举报
局长
发帖于6个月前 10回/2K+阅
共有10个评论 最后回答: 5个月前

Apache Solr 6现在的新功能能面向海量数据排序,导出,deep page,甚至是MapReduce,这些文档,原理的描述,十分匮乏。

二元分词法不依赖中文词典,连古诗词都能搜:

PHP实现中文二元分词:
原文字数为n,分词后的字数为2n-2,分词字数约为原文字数的2倍.
<?php
if(preg_match_all('%[\x{4e00}-\x{9fa5}]%u', '坐观垂钓者', $matches)) {
	$size = count($matches[0]);
	for($i=0;$i<=$size-2;$i++) {
		$word = '';
		for($j=0;$j<2;$j++) {
			$word .= $matches[0][$i+$j];
		}
		echo $word."\n";
	}
}
// array ( 0 => '坐观', 1 => '观垂', 2 => '垂钓', 3 => '钓者' )

MySQL/SQLite等数据库都支持全文索引,所以用SQL就能进行全文检索:

用户搜索时输入的内容如"垂钓者"同理进行"俩俩组合分词",比如得到"垂钓"和"钓者".
全文检索的SQL语句:
SQLite: 
SELECT `docid` FROM post_fts 
WHERE `content` MATCH '垂钓 OR 钓者' 
ORDER BY `docid` DESC LIMIT 10 OFFSET 20;
MySQL: 
SELECT `docid` FROM post_fts 
WHERE MATCH(`content`) AGAINST('垂钓 OR 钓者' IN BOOLEAN MODE) 
ORDER BY `docid` DESC LIMIT 10 OFFSET 20;

SQLite官方测试中,50多万条数据用MATCH 'keyword'全文搜索仅耗时0.03秒(30毫秒).所以说,要做简单的站内搜索引擎,不一定非要用那些看起来高大上的Java方案,其实PHP+SQL就能解决.

--- 共有 1 条评论 ---
Minho丢人现眼啊。 6个月前 回复

引用来自“eechen”的评论

二元分词法不依赖中文词典,连古诗词都能搜:

PHP实现中文二元分词:
原文字数为n,分词后的字数为2n-2,分词字数约为原文字数的2倍.
<?php
if(preg_match_all('%[\x{4e00}-\x{9fa5}]%u', '坐观垂钓者', $matches)) {
	$size = count($matches[0]);
	for($i=0;$i<=$size-2;$i++) {
		$word = '';
		for($j=0;$j<2;$j++) {
			$word .= $matches[0][$i+$j];
		}
		echo $word."\n";
	}
}
// array ( 0 => '坐观', 1 => '观垂', 2 => '垂钓', 3 => '钓者' )

MySQL/SQLite等数据库都支持全文索引,所以用SQL就能进行全文检索:

用户搜索时输入的内容如"垂钓者"同理进行"俩俩组合分词",比如得到"垂钓"和"钓者".
全文检索的SQL语句:
SQLite: 
SELECT `docid` FROM post_fts 
WHERE `content` MATCH '垂钓 OR 钓者' 
ORDER BY `docid` DESC LIMIT 10 OFFSET 20;
MySQL: 
SELECT `docid` FROM post_fts 
WHERE MATCH(`content`) AGAINST('垂钓 OR 钓者' IN BOOLEAN MODE) 
ORDER BY `docid` DESC LIMIT 10 OFFSET 20;

SQLite官方测试中,50多万条数据用MATCH 'keyword'全文搜索仅耗时0.03秒(30毫秒).所以说,要做简单的站内搜索引擎,不一定非要用那些看起来高大上的Java方案,其实PHP+SQL就能解决.

学习了!

顶部