这一篇算给这一个系列告一个小的段落,之前开始写这些文章的时候,只是想把自己最近用Golang写的这个搜索引擎说一说,准备了大概3,4篇的量,但是一写下来,发现有点收不住,写到后面其实和Golang没什么关系了,主要在写搜索引擎的架构和一些数据结构了,我觉得这比写代码注释有用吧,而且通过这样写下来,我自己对这些个数据结构的理解也更深了。
一个月的时间,写了14篇了,虽然14篇文字不足以说明一个搜索引擎的实现,但我觉得基本上一些重要的东西我都说了,搜索引擎本身原理上其实比较简单,并且我们并没有涉及搜索引擎爬虫的部分,所以说起来并不是很复杂,复杂是复杂在外围一些算法上的东西,比如分词,比如排序之类的。
来看看我们都说了些啥
开了个头以后,先说了一下搜索引擎的基本概念,包括
docid
的概念,以及整个搜索引擎的分层情况然后说了倒排索引技术,也是搜索引擎最最底层和核心的概念了。
倒排索引分成词典和倒排文件两部分,接着说了一下倒排索引的词典的几种实现方式,包括哈希表和B+树的方式,并且简单介绍了一下跳表。
倒排索引技术说完了以后,按步骤的说了倒排索引的构建,包括全量和增量的构建,以及各种构建方式,最后说了一下我的构建方法。
倒排的原理,数据结构,构建方式介绍完了以后花了一篇介绍了一下正排索引。
倒排和正排两个基础数据结构说完了以后说了索引的分段策略,分段是为了更灵活的使用索引而出现的一种技术。
段之后就是索引层了,索引层先说了数据如何进行增删改。
最后介绍了一下数据的检索,包括一些求交集,求并集的过程,这一篇实际上就是索引层之上的引擎层做的事了。
然后除了上面这些,穿插的说了一下搜索引擎的一些外围的技术,包括文本相关性,排序,机器学习和长尾词的一些问题。
照这样,第一部分应该差不多可以结束了,一个单机版的搜索引擎只需要上面一些东西就可以完整的实现了,也欢迎大家去我的github上看看,目前开源出来的就是一个简单的单机版的搜索引擎了,主要的结构如下,很简单的,欢迎提交bug,由于是自己的玩具项目,没有写单元测试,代码中的_test.go文件都是功能测试。
但是,这个系列也远没结束,关于搜索引擎还有好多可以说的,并且索引分片和分布式都还没开始呢,只是第一部分的单机版的结束了,后面会用一个系列说一下搜索引擎的分布式实现,当然代码也会跟着更新。
后面的文章更新还是会围着搜索,推荐和广告这三个方面来说,我觉得这三个其实是一体的,用的技术也差不多,算法上三个看上去有区别,其实底层也差不太多,特别是广告,简直就是推荐+搜索的组合,所以文章在架构和算法上也都会涉及到,当然也会有比较扯淡的文章,比如今天这篇。
最后,既然是Golang写的搜索引擎,那么我们来聊聊Golang吧。
用了快一年的Golang了,我是从C/C++转过来的,之前近10年都在和C++打交道,除了C/C++,用过python,objective-C,C#,Lua,Erlang,很抱歉,没有用过世界上最好的语言PHP,也没有用过世界上最火的语言JAVA(用来写hadoop作业应该不算用JAVA吧),我个人觉得Golang设计出来完全就是一门工程性的语言,工程性非常强,确实很适合后台类型的开发。
这里不做语言之争,仅写写我的一些感受吧,总的来说,我个人觉得Golang非常棒。
我们来先说好的
开发效率和之前的c比起来不知道高了多少倍,基础数据结构比较全,其实主要就是map啦。
更舒服的是感觉用起来和c差别不大,有指针哦,这点对于一个C程序员来说很重要哦。
把接口用活就能写出好的Golang代码,设计模式那一套不用套来套去了,当然,设计模式那一套思想我觉得还是很有用的。
error返回值,这点可能个人爱好吧,我觉得挺好,不用去捕获什么异常了,特别JAVA那种(虽然没写过,但JAVA代码还是看过不少的)一个异常可以像盗梦空间一样抛出好几层简直就是噩梦,出错了就出错了呗,返回错误就行,还来个什么异常做甚。
协程和管道就不说了,各种讨论已经很多了。
高阶函数,闭包随便搞,很多新的函数式编程思想也可以比较舒服的用在golang中
调试也不错,可以用GDB,然后还有个性能测试工具也挺好,基本上这两个再加上printf就能搞定几乎所有的bug和性能瓶颈了。
坏的呢?
垃圾回收应该算是个优点,让你不用关心new了的对象什么时候释放,但作为一个老程序员,有些时候(其实是很多时候)你并不知道你的程序的内存空间是什么样子的,特别是一个搜索引擎的开发,本来就吃内存,你还不确定内存用了多少,用在了什么地方,还是很不爽的,不如自己new自己delete来得直接,虽然自己管理有可能有内存泄露,那改bug就好了,改到不泄露呗。当然,你可以说出一万个有自动垃圾回收的语言的好处,但我也能说出一个自己管理内存的好处:自由。
没有泛型,没有泛型,没有泛型!无力吐槽。据说也不准备加。
不支持动态加载.so,这个其实很重要,特别是不能停机的服务,比如搜索引擎,如果可以动态加载.so,那修改算法,修改策略,分分钟上线而不用停服,不过好像1.6支持了?我没关注过不知道,我现在用的还是1.4.2
总的来说,我还是非常非常推荐Golang的,下次有时间试试Rust,看看如何,不过我个人不太看好Rust,现在编程语言这么多,还有PHP这种王牌语言,一个崭新的语言后面没有一个强大的公司支撑的话,最后不管多牛逼也只能呵呵。
最后,我的这个开源项目(https://github.com/wyh267/FalconEngine),我会坚持写下去,变成一个分布式的搜索引擎,希望在性能上能达到ES的水平吧,也欢迎大家关注,之前是为了熟悉搜索引擎本身数据结构,所以自己撸了很多基础代码,后面为了能让更多人用起来,也为了稳定性我会引入一些开源的组件而不是自己造轮子了。
想看之前所有文章,可以关注公众号,然后点击公众号的菜单即可:)或者直接看SF的专栏也行。
欢迎关注我的公众号,文章会在这里首先发出来:)扫描或者搜索微信号XJJ267或者搜索中文西加加语言就行