悟空:用Go语言编写的全文搜索引擎

最近Go语言1.5版正式发布,国内关于Go语言的学习和应用也逐渐火热,InfoQ也将关注并推动国内Go语言社区的发展。悟空开源项目是用Go语言编写的全文搜索引擎,InfoQ记者采访了它的作者陈辉,了解了这个项目背后的一些信息。

\\

悟空搜索引擎的特点是高度可定制,具有如下特性:

\\

项目的架构如下图:

\\

a601d71a9264c1a88cb53944e4736f74.png

\\

引擎中处理用户请求、分词、索引和排序分别由不同的协程(goroutines)完成。

\\
  1. 主协程,用于收发用户请求\\t
  2. 分词器(segmenter)协程,负责分词\\t
  3. 索引器(indexer)协程,负责建立和查找索引表\\t
  4. 排序器(ranker)协程,负责对文档评分排序\

具体的原理可以在入门教程里查看,并且在这个教程里,作者用不到200行Go代码实现一个微博搜索网站。

\\

这个项目的作者是陈辉,以前在Google美国工作,2014年回国后加入阿里巴巴,现在是阿里巴巴广告事业部的大数据营销总经理。

\\

在这篇文档里,他谈到了创建悟空搜索引擎的初衷:

\\
\

知识应该容易获得

\\

……

\\

通用的搜索引擎并不能解决这个问题:首先,不能有针对性的垂直搜索,对内容的抓取和索引简单粗暴,无法得到结构化数据,看不到隐藏的内容属性;其次,通用搜索引擎对内容的排序无法进行定制,实时性不够,无法成为网站社区的有机的一部分。

\\

一个好的网络社区应该允许用户在阅读时搜索,搜索成为阅读的一部分;网站内部的流量应该是个性化的、有机的,而不应该由生硬的推荐系统主导用户阅读的方向。很可惜这样的网络社区很少,这种局面的造成一部分是因为缺乏一个开源的、容易定制的、高效的搜索引擎的存在。

\
\\

他的另一个初衷是认为搜索引擎技术应该普及:“所有大数据领域的工程师都应该在职业生涯的某个时刻试着重写一个搜索引擎,了解一下其中的技术问题,并尝试去解决这些问题。”

\\

InfoQ记者对他进行了采访,了解了他对Go语言的看法,以及悟空搜索引擎背后的一些故事。

\\

InfoQ:您是如何和Go语言结缘的,现在是否仍然关注Go语言?

\\
\

陈辉:最早是从Google内部的海报上知道Rob Pike给的TechTalk,关于一种新的编程语言,我对新的编程语言一直比较感兴趣,于是就去听了一下。

\\

当时在Google内部有一种鄙视Python的风气,有个资深的工程师还写了一篇文章《为什么你不应该用Python》,认为超过100行的代码就不应该用Python写。我自己在使用Python时也很头疼,感觉这就是一种ad hoc的语言,写出来的代码很不好维护,更要命的是还很丑陋,写完就不想再多看一眼。

\\

听完TechTalk的第一感觉就是Go可以取代Python进行快速开发,于是用Go写了几个内部小项目,非常顺手,当时Rob Pike还亲自review了我的代码,给了不少使用规范的建议。

\\

后来我的开源项目基本上都用Go写了,包括中文分词,机器学习等,见我的GitHub项目列表

\\

现在因为工作比较忙很少再写,不过如果有人想重头创作一个项目,我仍然会向他推荐Go。

\
\\

InfoQ:说说您使用Go语言的体会,它有哪些优缺点?

\\
\

陈辉:最大的优点是易于维护,代码写完之后几个月再去看完全没有生疏感,仿佛在Go中实现一个功能只有这么一种写法。而且还有gofmt这个格式化工具,让团队中所有人的代码风格都是一样的。Go是一种不会让团队其他小伙伴看代码时皱眉头的语言,没有什么比这更重要了。

\\

其次Go语言有C语言的优势,但没有C++的弱点。首先是强类型语言,任何严肃的软件项目都不应该选择使用弱类型语言。然后Go的interface能满足90%以上的OOP需求,但又没有C++的种种陷阱。最后,执行速度足够快。

\\

然后,Go有很好的代码管理、build和profiling功能。import一个GitHub的就好像使用本地目录一样,这天然解决了开源软件中的协同开发的问题。profiling的能力强大,加上build体系替代了一个好的IDE的最主要的功能。

\\

最后,goroutines提供了天然的并发编程支持,这也是我最喜欢使用的功能之一。

\\

当然它也不是没有缺点,在我眼里Go的缺点:对virtual function的支持不是很好(或者不存在?),无法通过继承实现代码复用。另外,pointer的使用有时候让人困惑。

\
\\

InfoQ:请介绍一下“悟空”开源项目的开发历史。

\\
\

陈辉:最早是13年7月开始写的,基本上是利用周末的时间,花了一个月写完了悟空最主要的代码,8月初扔到了GitHub上。14年一月份给引擎添加了持久存储,中间有几位contributor贡献了代码。

\\

透露一下,阿里巴巴内部有使用悟空。

\
\\

InfoQ:悟空和其它搜索引擎相比,有哪些特点?

\\
\

陈辉:据我所知还有一个Go写的搜索引擎,Bleve,不过好像不支持中文分词。

\\

悟空不是一个完整的搜索引擎,我也从来不打算让它变完整。我只想写一些容易被修改的、能融入你的业务需求的基础代码,这些代码只实现基本功能,同时也足够精简,让你能了然于心,可以快速修改实现你想要的功能。换句话说,你只要花一天时间就可以熟悉悟空的代码,让它成为你自己的搜索引擎。

\
\\

InfoQ:能否介绍一下悟空搜索引擎应用到高并发和大数据量场景下,可能会出现的性能瓶颈?以及有哪些优化手段?

\\
\

陈辉:目前悟空的索引结构都是基于内存的,单机的内存大小成为瓶颈。解决方式有两个,一是引入SSD等存储,二是分布到多台机器上。我比较倾向于后者,因为内存会越来越便宜。

\
\\

InfoQ:悟空搜索引擎未来有什么开发计划?

\\
\

陈辉:如果有时间,可能会加入docker的支持。

\
\\

如果你想了解更多关于悟空搜索引擎,这里有.NET社区知名开发者Oren Eini的一篇探索它代码的文章,感兴趣的读者可以阅读。

WuKong 全文搜索引擎。功能特性:高效索引和搜索(1M条微博500M数据28秒索引完,1.65毫秒搜索响应时间,19K搜索QPS)支持中文分词(使用sego分词包并发分词,速度27MB/秒)支持计算关键词在文本中的紧邻距离(token proximity)支持计算BM25相关度支持自定义评分字段和评分规则支持在线添加、删除索引支持持久存储可实现分布式索引和搜索采用对商业应用友好的Apache License v2发布示例代码:package main import (     "github.com/huichen/wukong/engine"     "github.com/huichen/wukong/types"     "log" ) var (     // searcher是协程安全的     searcher = engine.Engine{} ) func main() {     // 初始化     searcher.Init(types.EngineInitOptions{         SegmenterDictionaries: "github.com/huichen/wukong/data/dictionary.txt"})     defer searcher.Close()     // 将文档加入索引     searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"})     searcher.IndexDocument(1, types.DocumentIndexData{Content: "百度宣布拟全资收购91无线业务"})     searcher.IndexDocument(2, types.DocumentIndexData{Content: "百度是中国最大的搜索引擎"})     // 等待索引刷新完毕     searcher.FlushIndex()     // 搜索输出格式见types.SearchResponse结构体     log.Print(searcher.Search(types.SearchRequest{Text:"百度中国"})) } 标签:WuKongSearch
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值