C++写一个微博全文搜索引擎

来源:互联网 发布:mysql压缩包安装教程 编辑:程序博客网 时间:2024/05/16 06:50

用C++写的全文搜索引擎

项目背景

现在我们可以在我们可以很容易的在网上搜索到海量的信息,有些网站往往拥有很多优秀的内容,但是缺乏一个灵活而且高效的搜索引擎,导致这个网站的价值没有很好的体现,基于时间轴的或者tag的推荐从另一种角度上来说其实是忽视了用户搜索的主观能动性。

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

我们如果能够解决这两个问题,那么相信网站内容的价值也会更好的得到体现,同时用户也会越来越适应通过站内搜索引擎更好的获取自己需要资源。

这个项目就是为了实现这样理想的一个尝试。

功能综述

  • 利用redis存储倒排索引和网页库(均在内存),实现高速搜索
  • 利用redis建立缓存,若在缓存直接命中,查询相应速度提高100倍之多
  • 支持中文分词(cppjieba)
  • 支持持久化存储(redis)
  • 采用log4cpp作为日志系统

项目架构

离线索引模块

去重算法:simhash指纹,针对每个新加入网页计算指纹,和指纹库里的指纹进行比较,若重复(海明距离小于3),就不会加入索引库和网页库
数据结构:{string : {ID : weight},{ID : weight}…},weight(权重)是通过TD-IDF算法并归一后的权重
存储结构:用redis 的set存储:结构为 key:string set :string(string 需要解析 是ID 和 weight组成的字符串)

查询模块

网页排序:BM25算法 + vsm 之前采用空间向量模型和BM25算法结合(两个算法本来就有共通的地方)增加一些定制性
线程模型:task threadpool 任务队列
缓存模块

内存实现:利用unordered_map 作为缓存数据结构,每个线程维护一个缓存,线程池维护一个缓存,利用timerfd+poll实现缓存动态更新和存盘
redis实现:利用redis的string数据结构来存储缓存,缓存内容为封装好的json数组
网络库模块

网络模型:reactor模式,epoll + threadpool的实现i/o线程和计算线程分离

后期优化方向

加入推荐算法
利用Mysql存储网页库文件和索引文件
网络库采用muduo网络库的模型 实现 one loop per thread,实现更高的并发量
redis缓存相应参数的调整

源码地址:github
希望大家提出宝贵意见,一起交流

0 0
原创粉丝点击